Home > OS >  Spring oauth2login oidc grant access based on user info
Spring oauth2login oidc grant access based on user info

Time:12-24

I'm trying to set up Authentication based on this tutorial: https://www.baeldung.com/spring-security-openid-connect part 7 specifically.

I have filled properties and configured filter chain like this:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .authorizeRequests(authorizeRequests -> authorizeRequests
        .anyRequest().authenticated())
      .oauth2Login(oauthLogin -> oauthLogin.permitAll());
    return http.build();
}

which works, but now all users from oidc can connect log in. I want to restrict access based on userinfo. E.g. add some logic like:

if(principal.getName() == "admin") {
//allow authentication
}

are there any way to do it?

I tried to create customer provider like suggested here: Add Custom AuthenticationProvider to Spring Boot oauth oidc

but it fails with exception and says that principal is null.

CodePudding user response:

You can retrieve user info when authentication is successful and do further checks based user info. Here is sample code that clears security context and redirects the request:

@Component
public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        if(authentication instanceof OAuth2AuthenticationToken) {
            OAuth2AuthenticationToken token =  (OAuth2AuthenticationToken) authentication;
            // OidcUser or OAuth2User
            // OidcUser user = (OidcUser) token.getPrincipal();
            OAuth2User user = token.getPrincipal();
            if(!user.getName().equals("admin")) {
                SecurityContextHolder.getContext().setAuthentication(null);
                SecurityContextHolder.clearContext();
                redirectStrategy.sendRedirect(request, response, "login or error page url");
            }
        }
    }
}

CodePudding user response:

Are you sure that what you want to secure does not include @RestController or @Controller with @ResponseBody? If so, the client configuration you are referring to is not adapted: you need to setup resource-server configuration for this endpoints.

I wrote a tutorial to write apps with two filter-chains: one for resource-server and an other one for client endpoints.

The complete set of tutorials the one linked above belongs to explains how to achieve advanced access-control on resource-server. Thanks to the userAuthoritiesMapper configured in resource-server_with_ui, you can write the same security expressions based on roles on client controller methods as I do on resource-server ones.

  • Related