I've been trying to implement a OAuth2 authentication server using the guides by Dave Syer with some inspiration from JHipster. But I can't figure out how it all works together.
It looks like the security setup using the WebSecurityConfigurerAdapter is overwritten when I use ResourceServerConfigurerAdapter.
@Configuration @EnableResourceServer public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter { private TokenExtractor tokenExtractor = new BearerTokenExtractor(); @Override public void configure(HttpSecurity http) throws Exception { http .addFilterAfter(contextClearer(), AbstractPreAuthenticatedProcessingFilter.class) .authorizeRequests() .anyRequest().authenticated().and().httpBasic(); } private OncePerRequestFilter contextClearer() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (tokenExtractor.extract(request) == null) { SecurityContextHolder.clearContext(); } filterChain.doFilter(request, response); } }; } @Component public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private final AuthenticationManager authenticationManager; @Autowired public CustomWebSecurityConfigurerAdapter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .parentAuthenticationManager(authenticationManager); } @Override protected void configure(HttpSecurity http) throws Exception { http .formLogin() .loginPage("/login").permitAll() .and() .authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .and() .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access") .and() .authorizeRequests().anyRequest().authenticated(); } }
This is code taken from a few different examples, so they might not mix that well. But I can't find a good documentation/example list for OAuth2 (unlike Spring Boot which has a awesome documentation), so I'm having problems understanding how thye all fit together. If I don't add the loginForm to the ResourceServerConfigurerAdapter, it will just give me unauthorized. But I defined it in the WebSecurityConfigurererAdapter as permitAll().
This is the AuthorizationServerConfigurerAdapter:
@Configuration @EnableAuthorizationServer public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("acme") .secret("acmesecret") .authorizedGrantTypes("authorization_code", "refresh_token", "password").scopes("openid"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); } }
Anything I'm doing wrong? Do I have to setup all the security within the ResourceServerConfigurerAdapter? Do I even need the WebSecurityConfigurerAdapter anymore?
If anyone know any guides, tutorials, blogs or anything alike that might help me wrap my head around how this works, that would be greatly appreciated.
Kind regards, Kenneth.
It serves as an open authorization protocol for enabling a third party application to get limited access to an HTTP service on behalf of the resource owner. It can do so while not revealing the identity or the long-term credentials of the user. A third-party application itself can also use it on its behalf.
Spring Security OAuth2 − Implements the OAUTH2 structure to enable the Authorization Server and Resource Server. Spring Security JWT − Generates the JWT Token for Web security. Spring Boot Starter JDBC − Accesses the database to ensure the user is available or not. Spring Boot Starter Web − Writes HTTP endpoints.
You need a WebSecurityConfigurerAdapter
to secure the /authorize endpoint and to provide a way for users to authenticate. A Spring Boot application would do that for you (by adding its own WebSecurityConfigurerAdapter
with HTTP basic auth). It creates a filter chain with order=0 by default, and protects all resources unless you provide a request matcher. The @EnableResourceServer
does something similar, but the filter chain it adds is at order=3 by default. WebSecurityConfigurerAdapter
has an @Order(100) annotation. So first the ResourceServer will be checked (authentication) and then your checks in your enxtension of WebSecurityConfigureAdapter will be checked.
Your configuration looks sane (the login chain takes precedence, but only matches a small set of requests).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With