I have a wicket 8 application that is using Spring security (Spring Boot 2.1.10) and is deployed on WebSphere traditional 8.5.5.x. WAS is connected to an LDAP. This application uses the J2EE (WAS) security. The server does have Kerberos configured.
I know WAS 8.5.5 does not officially support Spring boot 2.1.10 and Wicket 8. However, I have deployed this to a local WAS without the Kerberos configured and it works. This local WAS prompts for login. I do understand this could be a version problem. We would like the application to use the current Windows user to automatically log in (no login prompt to the user). When hitting the URL in the logs we see the application loops a number of times and each time it loops, it creates a session. I’m not sure where or why the session is being created. Eventually the browser shows the error ‘too many redirects’. I have seen 20 – 30 sessions created before it stops. I have set the Spring SessionCreationPolicy to each option and the behavior did not change. I want to secure the homepage – only users in a specific group should be able to access the home page. If they are not in the group, they should get redirected to an access denied page. Since we are having problems, I have modified the code to show the page if the user is authenticated. Once we get that working, we will add in the group membership. I have tried setting the role in the WebSession and then using @AuthorizeInstantiotion(“role”). I have also tried returning the page to display in the WebApplication class depending on if the user is signed in or not. Both just loop until it gives up. I do see all the output from the home page (SearchPage class) init, but then it loops and starts over. Code below: I do have a web.xml with a security constraint as it seems WebSphere needs this otherwise we don’t get a principal at all. <security-constraint> <web-resource-collection> <web-resource-name>User</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>AllAuthenticated</role-name> </auth-constraint> </security-constraint> *<!-- Security roles used in the application -->* <security-role> <role-name>AllAuthenticated</role-name> </security-role> My WebSession class: public class *AppWebSession* extends AbstractAuthenticatedWebSession { public volatile boolean signedIn; public *AppWebSession*(Request request) { super(request); *init*(); } private void *init*() { Injector.*get*().*inject*(this); log.*debug*("Session Injected."); } public static AppWebSession *get*(){ return (AppWebSession) Session.*get*(); } @Override public Roles *getRoles*() { log.*debug*("getRoles()"); Roles roles = new *Roles*(); if(AppWebSession.*get*().*isSignedIn*()){ // Because we are having problems, just set the role if isSignedIn = true. Later, we will set the roles based on group membership. roles.add(“HASACCESS”); return roles; } @Override public boolean *isSignedIn*() { signedIn = SecurityContextHolder.*getContext*().*getAuthentication* ().*isAuthenticated*(); log.*debug*("signedIn -> " + signedIn); <-- This shows ‘true’. return signedIn; } } My SecurityConfig class: @Configuration @EnableWebSecurity (debug = true) public class *AppSecurityConfig* extends *WebSecurityConfigurerAdapter* { private WebSpherePreAuthenticatedProcessingFilter wasPreAuthFilter = new *WebSpherePreAuthenticatedProcessingFilter*(); @Override protected void *configure*(HttpSecurity http) throws Exception { wasPreAuthFilter.*setAuthenticationManager*(*authenticationManager* ()); http .*addFilter*(wasPreAuthFilter) .*authorizeRequests*() .*anyRequest*().*permitAll*(); } @Override protected void *configure*(AuthenticationManagerBuilder auth) throws Exception { auth.*authenticationProvider*(*websphereAuthenticationProvider*()); } *// Required for WASPreAuth Filter* @Bean public AuthenticationProvider *websphereAuthenticationProvider*() { return new *AuthenticationProvider*() { @Override public Authentication *authenticate*(Authentication authentication) throws AuthenticationException { String groupName = "AD Group name"; PreAuthenticatedAuthenticationToken preAuthToken = new *PreAuthenticatedAuthenticationToken*(authentication.*getPrincipal*(), authentication.*getCredentials*()); try { Subject subject = WSSubject.*getCallerSubject*(); Optional<Principal> principal = subject.*getPrincipals* ().*stream*().*findFirst*(); if (principal.*isPresent*()) { log.*debug*("principal = " + principal.*get*(). *getName*()); } Optional<WSCredential> credentialStream = subject. *getPublicCredentials*(WSCredential.class).*stream*().*findFirst*(); List<GrantedAuthority> authorities = new ArrayList<>(); Stream<String> groupIds = credentialStream.*get*(). *getGroupIds*().*stream*(); Optional<String> group = groupIds.*filter*(i -> i. *contains*(groupName.*trim*())).*findFirst*(); if (group.*isPresent*()) { log.*debug*("group found: " + group.*get*()); authorities.*add*(new *SimpleGrantedAuthority* ("ROLE_HASACCESS")); } else { log.*debug*("Group not found"); } preAuthToken = new *PreAuthenticatedAuthenticationToken* (principal.*get*(), credentialStream.*get*(), authorities); } catch (WSSecurityException e) { log.*error*(e.*getMessage*(), e); } catch (CredentialExpiredException e) { log.*error*(e.*getMessage*(), e); } return preAuthToken; } @Override public boolean *supports*(Class<?> authentication) { return true; } }; } } My HomePage class: *// @AuthorizeInstantiation("hasAccess") Commented out and using the getHomePage logic* public class *SearchPage* extends *BasePage* { private IModel<AppSearchCriteria> searchCriteriaIModel = new Model<>(new *AppSearchCriteria*()); private boolean showSearchResults = false; public *SearchPage*() { super(); log.*debug*("SearchPage()"); } public *SearchPage*(IModel<AppSearchCriteria> model) { super(); log.*debug*("SearchPage(model)"); searchCriteriaIModel = model; } @Override protected void *onInitialize*() { super.*onInitialize*(); log.*debug*("SearchPage.init()"); Form<AppSearchCriteria> form = new Form<>("form", searchCriteriaIModel); log.*debug*("form created"); form.*type*(FormType.Horizontal); *add*(form); log.*debug*("form added"); log.*debug*("SearchPage.init() done"); } } >From the WebApplication class: @Override public Class<? extends Page> *getHomePage*() { log.*debug*("getHomePage()"); AppWebSession session = (AppWebSession)AppWebSession.*get*(); log.*debug*("Determine which page to show ..."); // This principal that is output is correct. log.*debug*("SecurityContextHolder principal: " + SecurityContextHolder.*getContext*().*getAuthentication*().*getPrincipal* ()); if (session != null) { if (session.*isSignedIn*()) { log.*debug*("signed in - returning SearchPage"); <-- I do see this output in the logs return SearchPage.class; } else { log.*debug*("session not signed in - returning NotAuthorized"); return NotAuthorized.class; } } else { log.*debug*("session is NULL - returning NotAuthorized"); return NotAuthorized.class; } }