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;

        }

    }

Reply via email to