0

I'm trying to get spring security roles to work with websphere liberty. I know I've got my liberty setup properly because I wrote a very simple servlet 3 app with role based restrictions and it worked on the same server with the same role restrictions.

Here is the relevant section of my SecurityConfig:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    LOGGER.info("adding testing constraint");
    http.authorizeRequests()
            .anyRequest().authenticated()
            .and().httpBasic();

    if (appProperties.isContainerManaged()) {
        LOGGER.info("using container managed");
        http.jee().mappableRoles("TESTING", "ADMIN");
    }
    http.csrf().disable()
            .logout()
            .permitAll();
}

The above is printing out "using container managed" in the server logs so I know that's working :)

In my controller I am passing in the principal:

public String index(final Model model, final Principal principal, final HttpSession session,
                    final HttpServletRequest request) {

But when I call:

Authentication authentication = (Authentication) principal;
authentication.getAuthorities()

I get nothing back.

Here is the relevant section of server.xml:

<application type="war" id="security-sample" name="security-test"
         location="${server.config.dir}apps/security-sample.war">
   <application-bnd>
       <security-role name="TESTING">
           <user name="myuser" />
       </security-role>
   </application-bnd>
</application>

I've dug a bit deeper. I converted the app to use the WebSpherePreAuthenticatedProcessingFilter. (I was shocked how little docs there are on this). I got the filter to load but it fails on Liberty with:

javax.naming.NameNotFoundException: UserRegistry

This looks to be a known problem:

https://www.ibm.com/developerworks/community/forums/html/topic?id=62b6761f-1ae4-42c3-847b-485acbd95730

From what I can tell, Liberty is just barely supported in Spring Security if you are using container managed security. You can get the user information, but not the group / role / authority info.

UPDATE:

I got a bit farther, I can now get a user's groups to show up in liberty but NOT the roles that are mapped via security-role.

Here's the trick. I created a LibertyPreAuthenticatedWebAuthenticatedDetailsSource that get's the user's groups. I used the calls here: http://www.ibm.com/support/knowledgecenter/SSD28V_8.5.5/com.ibm.websphere.wlp.core.doc/ae/rwlp_sec_apis.html to figure out how to get the groups for a user.

Now I just need to figure out how to use the mapped security roles....

David Parish
  • 111
  • 7
  • Do you eable the annotation ? http://docs.spring.io/spring-security/site/docs/current/reference/html/mvc.html#mvc-authentication-principal – chaoluo Dec 22 '16 at 02:18
  • @chaoluo do you mean the EnableWebSecurity annotation? Yes I've got that. Container managed security is working perfectly EXCEPT for authorities. – David Parish Dec 22 '16 at 15:55
  • `Authentication authentication = SecurityContextHolder.getContext().getAuthentication();` How about this? Is that null ? – chaoluo Dec 23 '16 at 01:20
  • No it's not null, but it still has the problem of no authorities. getAuthentication is really just returning the wrapped principal so it just reflects the same issue. – David Parish Dec 23 '16 at 17:03
  • Hi David, I have your similar problem but I cannot grant access to user and obtain a "Bad Credential" Error. Can you detail your solution with server.xml file, web.xml and your WebSecurityConfigurerAdapter class and any other you think relevant? Thanks – Neo1975 Nov 24 '17 at 09:09
  • Have you figured this? – pixel Jan 18 '23 at 02:58

1 Answers1

2

I've got this working with Java 11.0.8, Open Liberty 20.0.0.8 and Spring Boot 2.3.1. Here's the relevant Security Configuration. @DeclareRoles was necessary to enable the ROLE_ACTUATOR mapping, the .hasRole("ACTUATOR") method call was not sufficient.

@Configuration
@EnableWebSecurity(debug=true)
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@DeclareRoles({"ROLE_SERVICE","ROLE_ACTUATOR"})
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http)
    throws Exception
    {
        http.csrf().disable()
            .authorizeRequests()
                .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
                .anyRequest().authenticated()
            .and()
                .httpBasic()
            .and()
                .jee().mappableRoles("ACTUATOR","SERVICE")
            ;
    }

The relevant portions of server.xml

<basicRegistry>
    <user name="wsAdmin" password="{hash}ATAAAAAI4h/5AWC+TLRAAAAAIOI2KiXXXDx7mesI2R99XTI1D1rskbx2IGeOsroCkqZh"/>
    <user name="wsService" password="{hash}ATAAAAAItVt5WPc0H/NAAAAAIGSCDtS7RkFRXeG6v3hOqUAkcAdLme5Pmx1bSNsk9kVN"/>
</basicRegistry>

<webApplication context-root="sample" type="war" location="C:\Deploy\sample-0.0.1-SNAPSHOT.war" >
    <application-bnd>
        <security-role name="ROLE_SERVICE">
            <user name="wsService" />
        </security-role>
        <security-role name="ROLE_ACTUATOR">
            <user name="wsAdmin" />
        </security-role>
    </application-bnd>
</webApplication>

Generating these log entries for the mapping

[2020-09-29T14:55:50.212-0400] 0000002f SystemOut     O   2020-09-29 14:55:50.211 DEBUG 11460 --- [ecutor-thread-9] p.j.J2eePreAuthenticatedProcessingFilter : PreAuthenticated J2EE principal: wsService
[2020-09-29T14:55:50.213-0400] 0000002f SystemOut     O   2020-09-29 14:55:50.212 DEBUG 11460 --- [ecutor-thread-9] p.j.J2eePreAuthenticatedProcessingFilter : preAuthenticatedPrincipal = wsService, trying to authenticate
[2020-09-29T14:55:50.217-0400] 0000002f SystemOut     O   2020-09-29 14:55:50.217 DEBUG 11460 --- [ecutor-thread-9] henticatedWebAuthenticationDetailsSource : J2EE roles [[ROLE_SERVICE]] mapped to Granted Authorities: [[ROLE_SERVICE]]


[2020-09-29T14:56:43.558-0400] 00000035 SystemOut     O   2020-09-29 14:56:43.558 DEBUG 11460 --- [cutor-thread-13] p.j.J2eePreAuthenticatedProcessingFilter : PreAuthenticated J2EE principal: wsAdmin
[2020-09-29T14:56:43.558-0400] 00000035 SystemOut     O   2020-09-29 14:56:43.558 DEBUG 11460 --- [cutor-thread-13] p.j.J2eePreAuthenticatedProcessingFilter : preAuthenticatedPrincipal = wsAdmin, trying to authenticate
[2020-09-29T14:56:43.559-0400] 00000035 SystemOut     O   2020-09-29 14:56:43.559 DEBUG 11460 --- [cutor-thread-13] henticatedWebAuthenticationDetailsSource : J2EE roles [[ROLE_ACTUATOR]] mapped to Granted Authorities: [[ROLE_ACTUATOR]]
Dwight Shih
  • 91
  • 1
  • 4
  • It worked for me. Only thing I changed is instead requestMatcher I have used antMatchers: .antMatchers("/app/*").hasRole("ACTUATOR") .antMatchers("/app_test/*").hasRole("ACTUATOR") – Waqar Detho Jun 01 '21 at 14:20