Spring oauth2 and digest authentication will work together - spring

I have added spring oauth2 into my restful service. Most of the services are consumed by my own portal so getting the token then calling the api is fine. However i have exposed some more web services which has to be called without this token concept. Those consumers have username and password.
The best example is Swagger implementation. Where opening the swagger page should be authenticated via digest instead of oauth token.
The below code changes i made but it is not working.
I believe, i no need to call oauth server from the resource server in this case. So just made the below code within the resource server. But seen the problem like after authentication page accepted my credentials it is again rerouting/redirecting to the same authentication page.
Please help.
#Configuration
#EnableResourceServer
public class ResourceServerImpl extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().requestMatchers().antMatchers("/**").and().authorizeRequests()
.antMatchers(HttpMethod.POST, "/url1/path1/path2").hasAnyAuthority( "FUNCTION_FN1")
.antMatchers(HttpMethod.GET, "/url2/path1/path2").hasAnyAuthority( "FUNCTION_FN2")
.antMatchers("/swagger-ui.html").hasRole("USER")
.anyRequest().authenticated()
.and().formLogin().and().httpBasic()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
#Configuration
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}
UPDATE
I dont think this is possible to make some request to be authenticated with DIGEST and some are with OAUTH. So currently i made swagger url also to be authenticated with oauth token, instead of digest support.

Yes, it's definitely possible to configure multiple authorization mechanisms in the same application. Distinct instance of WebSecurityConfigurerAdapter should be provided for each mechanism.
#EnableResourceServer and #EnableAuthorizationServer provide corresponding oauth adapters. ApiSecurityConfiguration provides adapter for basic auth.
Here is minimal working sample for basic and oauth2:
#SpringBootApplication
public class TestApp {
#RestController
public static class Endpoints {
// doesn't require any authentication
#RequestMapping("/test")
public String test() {
return "no auth";
}
// requires basic authentication
#RequestMapping("/api/test")
public String apiTest() {
return "basic auth";
}
// requires oauth authentication
#RequestMapping("/oauth/test")
public String oauthTest() {
return "oauth";
}
}
#Configuration
#EnableWebSecurity
public static class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests().antMatchers("/api/**").hasRole("USER")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
}
#Configuration
#EnableAuthorizationServer
public static class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("test")
.secret("test")
.authorizedGrantTypes("client_credentials")
.authorities("USER")
.scopes("read", "write", "test")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(120);
}
}
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/**")
.and()
.authorizeRequests().antMatchers("/oauth/**").authenticated();
}
}
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
}
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>

Related

Swagger OpenAPI UI sending 403 response status for POST, PUT and DELETE Requests : Server hosted behind Nginx Proxy

Issue :
Get request for Swagger UI openAPI is working , whereas other method types giving 403 error.
Dependency :
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.6</version>
</dependency>
Swagger Configuration :
#Configuration
#OpenAPIDefinition(servers = {
#Server(url = "https://hostname")
})
#SecurityScheme(name = auth, type = SecuritySchemeType.HTTP, bearerFormat = "JWT", scheme = "bearer")
public class SwaggerConfig {
}
Security Configuration :
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui/**","/v3/api-docs/**");
}
}
We have also tried ignoring these paths : /swagger-resources/** , /webjars/** in WebSecurity, still its not working.
Post Request Error message 403
Original Edit : On some further research , found that's it may be because of the nginx proxy. Everything is working fine on my local but not working on other environments that are hosted behind the nginx proxy.
This is my solution described in the comments. I have a also a configuration for #Order(1) that is for the rest of my application.
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] WHITELIST = {
"/v2/api-docs",
"/v3/api-docs",
"/**/v3/api-docs",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"**/swagger-ui.html",
"/**/swagger-ui.html**",
"/swagger-ui.html**",
"/webjars/**"
};
#Configuration
#Order(2)
public static class SwaggerSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(WHITELIST).permitAll();
http.csrf().disable();
}
}
}

Spring Boot 2.5.3 OAuth2 - Auth-Server and Webservice separate, Login error

Following the example on https://developer.okta.com/blog/2019/03/12/oauth2-spring-security-guide using the projects Create an OAuth 2.0 Server and Build Your Client App I cannot get it running without error.
I don't use Thymeleaf, as my Webservice returns data, not a page.
OAuth 2.0 Server project
#SpringBootApplication
#EnableResourceServer
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
}
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
public AuthorizationServerConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("abcd")
.secret(passwordEncoder.encode("fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9"))
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true)
.redirectUris("http://localhost:8082/login/oauth2/code/");
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");;
}
}
#Configuration
#Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("john")
.password(passwordEncoder().encode("doe"))
.roles("USER");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
#RestController
public class UserController {
#GetMapping("/user/me")
public Principal user(Principal principal) {
return principal;
}
}
application.properties
server.port=8090
pom.xml
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
I omit the context path, which the project originally uses.
Webservice project
#RestController
public class MyRESTController {
#GetMapping("/securedPage")
public String securedPage(Principal principal) {
return "securedPage";
}
#GetMapping("/")
public String index(Principal principal) {
return "index";
}
}
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
application.properties
server.port=8082
server.servlet.session.cookie.name=UISESSION
spring.security.oauth2.client.registration.custom-client.client-id=abcd
spring.security.oauth2.client.registration.custom-client.client-secret=fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9
spring.security.oauth2.client.registration.custom-client.client-name=Auth Server
spring.security.oauth2.client.registration.custom-client.provider=custom-provider
spring.security.oauth2.client.registration.custom-client.scope=user_info
spring.security.oauth2.client.registration.custom-client.redirect-uri=http://localhost:8082/login/oauth2/code/
spring.security.oauth2.client.registration.custom-client.client-authentication-method=basic
spring.security.oauth2.client.registration.custom-client.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.custom-provider.authorization-uri=http://localhost:8090/oauth/authorize
spring.security.oauth2.client.provider.custom-provider.token-uri=http://localhost:8090/oauth/token
spring.security.oauth2.client.provider.custom-provider.user-info-uri=http://localhost:8090/user/me
spring.security.oauth2.client.provider.custom-provider.user-name-attribute=name
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
When running both porojects, with localhost:8082 in the web browser I get index as response.
With localhost:8082/securedPage I get redirected to the login page, entering username john and password doe I get the following error page:
Login with OAuth 2.0
[invalid_user_info_response] An error occurred while attempting to retrieve the UserInfo Resource: 404 : [{"timestamp":"2021-07-30T07:58:54.529+00:00","status":404,"error":"Not Found","path":"/user/me"}]
Auth Server
Don't know what the error is causing. Looks like it is related to the Webservice application property and the URL to the UserController in the OAuth 2.0 Server project
spring.security.oauth2.client.provider.custom-provider.user-info-uri=http://localhost:8090/user/me
One additional question is:
Can the login form be avoided? The credentials passed somehow.
If the client is not the web browser but some other application which has no UI. Or perhaps curl. I also have MockMvc tests, so far it was Basic Auth, now OAuth2, how will be those affected?

Spring Security inmemory authentication issue

I am using Spring Security inmemory authentication, but it is not working properly.
It is generating default password but it is not taking the user and password I generated in configuration. Below is my controller:
#CrossOrigin(origins = "*")
#EnableAutoConfiguration
#RestController
#RequestMapping("/api")
public class AppController {
#RequestMapping(value="/hello", method=RequestMethod.GET, produces="text/plain")
public String sayHello() {
return "Hello welcome to spring security!!!!";
}
}
And below is my security configuration class:
#Component
#EnableWebSecurity
/*#EnableGlobalMethodSecurity*/
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class
})
public class SecurityProvider extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/*").hasRole("ADMIN")
.and()
.formLogin();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("ramu")
.password("password")
.roles("ADMIN")
.and()
.withUser("gopal")
.password("password")
.roles("USER");
}
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
// ALTHOUGH THIS SEEMS LIKE USELESS CODE,
// ITS REQUIRED TO PREVENT SPRING BOOT AUTO-CONFIGURATION
return super.authenticationManagerBean();
}
}
I also tried by excluding SecurityAutoconfiguration.class at main application by using below annonation:
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class })
public class App {
public static void main( String[] args ) {
SpringApplication.run(App.class, args);
}
}
But no luck, it is not taking the username and password I configured in my configuration class.
I fixed your setup, see the code below.
The WebSecurityConfig (instead of the former ServiceProvider component):
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("/api/*").hasRole("ADMIN").and().formLogin();
}
PasswordEncoder passwordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("ramu")
.password("password")
.roles("ADMIN")
.and()
.passwordEncoder(passwordEncoder)
.withUser("gopal")
.password("password")
.roles("USER");
}
}
The RestController:
#CrossOrigin(origins = "*")
#EnableAutoConfiguration
#RestController
#RequestMapping("/api")
public class AppController {
#RequestMapping(value="/hello",method=RequestMethod.GET,produces="text/plain")
public String sayHello(){
return "Hello welcome to spring security!!!!";
}
}
What I had to change:
ServiceProvider #Component -> WebSecurityConfig #Configuration
I registered a PasswordEncoder
I reverted all of the #EnableAutoConfiguration annotations
I reverted the AuthenticationManager Bean
I used the spring-parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Solution for spring-boot-starter-parent version 1.5.7.RELEASE:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("/api/*").hasRole("ADMIN").and().formLogin();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication()
.withUser("ramu")
.password("password")
.roles("ADMIN")
.and()
.withUser("gopal")
.password("password")
.roles("USER");
}}
Maybe consider to use a kind of passwordEncoder here as well.

Spring Boot Swagger UI - Protect UI Access

I added a simple swagger UI to my existing springboot REST API by adding the following class to my code:
#EnableSwagger2
#Configuration
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.paths(PathSelectors.regex("/v1.*"))
.build()
.pathMapping("/")
.apiInfo(metadata());
}
private ApiInfo metadata() {
return new ApiInfoBuilder()
.title("My awesome API")
.description("Some description")
.version("1.0")
.build();
}
}
My problem is that the API should be public, but the swagger docs should not. I would like a way of requesting authentication to the swagger documentation, anyone knows any simple way of achieving this?
I tried to google it but I could only find OAth stuff, but this is authentication for the endpoints not the swagger documentation...
Swagger docs will be available at /v2/api-docs endpoint when swagger integrated with spring boot application.
Inorder to protect the resource , make use of spring security and restrict the endpoint for accessing the docs
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Security configuration : restricting access to the endpoint only to the users
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/v2/api-docs").authenticated()
.and()
.httpBasic();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
Additionally, swagger-ui.html can also be secured based on the requirement.
Here's a an alternative solution. This is about limiting access to swagger only in development/qa environment. The production environment will not have access to Swagger. I am using a property (prop.swagger.enabled) as a flag to bypass spring security authentication for swagger-ui only in development/qa environment.
#Configuration
#EnableSwagger2
public class SwaggerConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
#Value("${prop.swagger.enabled:false}")
private boolean enableSwagger;
#Bean
public Docket SwaggerConfig() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(enableSwagger)
.select()
.apis(RequestHandlerSelectors.basePackage("com.your.controller"))
.paths(PathSelectors.any())
.build();
}
#Override
public void configure(WebSecurity web) throws Exception {
if (enableSwagger)
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (enableSwagger) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
}
I use this boiler plater to configure and secure swagger
#Configuration
#EnableSwagger2
public class SwaggerConfig extends WebSecurityConfigurerAdapter {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**")
.authenticated().and().httpBasic();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

spring boot oauth2 configuration: resource server remains unprotected

I have implemented authorization server and resource server using spring boot. authorization server works fine and I am able to get tokens. But my resource server remains unprotected. My objective is that resource server ahould only be accessed by someone having valid access token.
My entire code is:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
TokenStore tokenStore;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("client")
.scopes("read", "write")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.authorizedGrantTypes("password", "refresh_token")
.secret("secret")
.accessTokenValiditySeconds(180)
.refreshTokenValiditySeconds(600);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security); //To change body of generated methods, choose Tools | Templates.
}
}
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Autowired
private TokenStore tokenStore;
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenServices(tokenServices())
.resourceId("MY_RESOURCE");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable()
.requestMatchers().antMatchers("/**")
.and()
.authorizeRequests()
.antMatchers("/").access("hasRole('USER')")
.antMatchers("/secure/").access("hasRole('ADMIN')")
.and()
.exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
return defaultTokenServices;
}
}
#Configuration
#EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("bill").password("abc123").roles("ADMIN").and()
.withUser("bob").password("abc123").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
}
#Configuration
#EnableGlobalMethodSecurity
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
#SpringBootApplication
#RestController
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#GetMapping(value = "/")
public ResponseEntity<?> hello(){
return ResponseEntity.ok("Hello World");
}
#GetMapping(value = "/secure/")
public ResponseEntity<?> secure(){
return ResponseEntity.ok("Secure Resorce");
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>boot-oauth2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>boot-oauth2</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
What am I missing?
Thanks for help.
UPDATE:
I figured out that my resource server is unprotected because of presence of OAuth2SecurityConfig class. If I remove this class and add following class (where I have moved the inMemmory users), then resource server is protected as required
#Configuration
public class WebSecurityGlobalConfig extends GlobalAuthenticationConfigurerAdapter {
#Autowired
UserService userService;
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("bill").password("abc123").roles("ADMIN").and()
.withUser("bob").password("abc123").roles("USER");
}
}
So, I am sensing improper HttpSecurity configuration in OAuth2SecurityConfig class is conflicting with resource server config.
So, How can I configure HttpSecurity of OAuth2SecurityConfig so, that it does allow access token protection for resource server paths and normal web security for non-resource server paths
finally after a lot of googling, I found the solution.
It was due to order of filters. order of OAuth2 resource filter has been changed in spring-boot-1.5.1. as change log says
The default order of the OAuth2 resource filter has changed from 3 to
SecurityProperties.ACCESS_OVERRIDE_ORDER - 1. This places it after the
actuator endpoints but before the basic authentication filter chain.
The default can be restored by setting
security.oauth2.resource.filter-order = 3
So, I changed the order of my OAuth2 resource server filter to 3 by setting it in application.properties security.oauth2.resource.filter-order = 3 and my problem was solved.
Annotate your OAuth2SecurityConfig with #EnableGlobalMethodSecurity(prePostEnabled = true)
I had the same issue.
I had another class extending WebSecurityConfigurerAdapter that i guess was in conflict with AuthorizationServerConfigurerAdapter.
I just removed the WebSecurityConfigurerAdapter class and it worked.

Resources