Spring Boot Swagger UI - Protect UI Access - spring

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");
}
}

Related

Spring Boot 3 security cannot access H2 console - 403

I'm in the process of re-learning Spring security in Spring Boot 3. Things changed a little and for some reason the same settings working for WebSecurityConfigurerAdapter's config method will not work in SecurityFilterChain.
HERE IS SOME CODE FROM PREVIOUS SETUPS- WORKING
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AppUserService userService;
private final PasswordEncoder bCryptPasswordEncoder;
public SecurityConfig(AppUserService userService, PasswordEncoder bCryptPasswordEncoder) {
this.userService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
private static final String[] SWAGGER = {
"/v2/api-docs",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
"/v3/api-docs/**",
"/swagger-ui/**"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.cors(c -> {
CorsConfigurationSource cs = request -> {
CorsConfiguration cc = new CorsConfiguration();
cc.setAllowedOrigins(List.of("*"));
cc.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
cc.setAllowedHeaders(List.of("Origin", "Content-Type", "X-Auth-Token", "Access-Control-Expose-Header",
"Authorization"));
cc.addExposedHeader("Authorization");
cc.addExposedHeader("User-Name");
return cc;
};
c.configurationSource(cs);
});
http.headers().frameOptions().disable();
http.sessionManagement().sessionCreationPolicy(STATELESS);
http.authorizeRequests().antMatchers("/login/**").permitAll();
http.authorizeRequests().antMatchers("/h2-console/**").permitAll();
http.authorizeRequests().antMatchers(SWAGGER).permitAll();
http.authorizeRequests().antMatchers("/users/password-reset-request").permitAll();
http.authorizeRequests().antMatchers("/users/password-change").permitAll();
http.authorizeRequests().antMatchers("/users/**").hasAnyAuthority("ADMIN");
http.authorizeRequests().antMatchers("/favorites/**").hasAnyAuthority("USER");
http.authorizeRequests().antMatchers(GET).hasAnyAuthority("USER");
http.authorizeRequests().antMatchers(POST).hasAnyAuthority("USER");
http.authorizeRequests().antMatchers(PUT).hasAnyAuthority("USER");
http.authorizeRequests().antMatchers(DELETE).hasAnyAuthority("MODERATOR");
http.authorizeRequests().anyRequest().authenticated();
http.addFilter(new CustomAuthenticationFilter(authenticationManager()));
http.addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected UserDetailsService userDetailsService() {
return userService;
}
}
NOW SINCE
WebSecurityConfigurerAdapter
is no longer available:
#Configuration
#EnableWebSecurity
#RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final AuthenticationProvider authenticationProvider;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable();
http.headers().frameOptions().disable();
http.sessionManagement().sessionCreationPolicy(STATELESS);
http.authorizeHttpRequests().requestMatchers("/h2-console/**").permitAll();
http.authorizeHttpRequests().requestMatchers("/auth/**").permitAll();
http.authorizeHttpRequests().anyRequest().authenticated();
http.authenticationProvider(authenticationProvider);
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Long story short- previously working
http.headers().frameOptions().disable();
http.authorizeRequests().antMatchers("/h2-console/**").permitAll();
Will not work as
http.headers().frameOptions().disable();
http.authorizeHttpRequests().requestMatchers("/h2-console/**").permitAll();
Application.properties for H2 database are exact same, copied. I didn't changed default url for H2. It seems its the Spring Security standing in the way.
Please advice what to do.
Do you have any knowlage if anything changed for H2 setup since previous Spring Boot?
EDIT: If I simply http.authorizeHttpRequests().anyRequest().permitAll();, the console will work. It must be security related
The H2ConsoleAutoConfiguration will register a Servlet for H2's Web Console, therefore, the servletPath property is needed in order to use the MvcRequestMatcher, like so:
#Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) {
// ...
MvcRequestMatcher h2RequestMatcher = new MvcRequestMatcher(introspector, "/**");
h2RequestMatcher.setServletPath("/h2-console");
http.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(h2RequestMatcher).permitAll()
// ...
);
}
In summary, we are permitting every (/**) request under the h2-console servlet path.
Another option is to use PathRequest.toH2Console() as shown in the Spring Boot H2 Console's documentation, which in turn will create an AntPathRequestMatcher for you.
#Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) {
// ...
http.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(PathRequest.toH2Console()).permitAll()
// ...
);
}
This problem has also been answered in the project's repository

Spring Security does not reject requests when missing HTTP basic authentication header

I'm trying to setup a simple HTTP basic authentication mechanism for accessing REST endpoints in an application.
Basically, all endpoints starting with /api/internal shall be secured with HTTP basic authentication, while further configurations shall secure other paths with e.g. OAuth2.
The problem is that, for example, a GET request to /api/internal/test is allowed even when the client does not provide any credentials in the request header.
This is my current security configuration class:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Order(1)
#Configuration
#EnableWebSecurity
public static class InternalApiSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
final PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user")
.password(passwordEncoder.encode("password"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.mvcMatcher("/api/internal/**")
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
}
// Other security configuration follow here...
}
After having spent some more time on this problem, I found that the authentication works when adding the following to the chain:
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

401 unauthorized page for swagger-ui

I have a problem with springfox in particular with swagger-ui. I have added this dependencies of springfox in my pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
but when I reach swagger-ui with the url localhost:8889/app/swagger-ui.html it come back to me error 401 (my context path is '/app' and my web server start on port 8889(http)). I have also tried with the following url:
localhost:8889/app/swagger-ui
localhost:8889/swagger-ui.html
localhost:8889/swagger-ui
but the result is always the same. I have tried to reach the localhost:8889/app/v2/api-docs and this works fine (I see the json value not in human format), so swagger is working
I have configured a class of configuration for swagger in this way:
#Configuration
#EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer{
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(this.apiInfo())
.useDefaultResponseMessages(false);
}
private ApiInfo apiInfo() {
ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
apiInfoBuilder.title("REST API");
apiInfoBuilder.description("REST API GENERATION");
apiInfoBuilder.version("1.0.0");
apiInfoBuilder.license("GNU GENERAL PUBLIC LICENSE, Version 3");
apiInfoBuilder.licenseUrl("https://www.gnu.org/licenses/gpl-3.0.en.html");
return apiInfoBuilder.build();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/api/v2/api-docs", "/v2/api-docs");
registry.addRedirectViewController("/api/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/api/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/api/swagger-resources", "/swagger-resources");
}
}
I have configured also a spring security class and I have modified the configure method to ignore this request pattern:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#PropertySource(encoding = "UTF-8", value = {"classpath:commons-web-
config.properties"}, ignoreResourceNotFound = false)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private TokenAuthenticationProvider authenticationProvider;
private static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/public/login/login-user")
);
private static final RequestMatcher PROTECTED_URLS = new NegatedRequestMatcher(PUBLIC_URLS);
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Override
public void configure(WebSecurity web) {
web
.ignoring()
.requestMatchers(PUBLIC_URLS);
web
.ignoring()
.antMatchers("/v2/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/public/**", "/websocket/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http
.sessionManagement().sessionCreationPolicy(STATELESS)
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/protected/my-controller")
.hasAnyRole("SUPER-ADMIN","ADMIN","USER")
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter.class)
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
#Bean
public AuthenticationEntryPoint forbiddenEntryPoint() {
return new HttpStatusEntryPoint(FORBIDDEN);
}
#Bean
public TokenAuthenticationFilter restAuthenticationFilter() throws Exception {
TokenAuthenticationFilter filter = new TokenAuthenticationFilter(PROTECTED_URLS);
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(successHandler());
return filter;
}
#Bean
public SimpleUrlAuthenticationSuccessHandler successHandler() {
SimpleUrlAuthenticationSuccessHandler successHandler = new SimpleUrlAuthenticationSuccessHandler();
successHandler.setRedirectStrategy(new NoRedirectStrategy());
return successHandler;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public FilterRegistrationBean<TokenAuthenticationFilter> disableAutoRegistration(TokenAuthenticationFilter filter) {
FilterRegistrationBean<TokenAuthenticationFilter> registration = new FilterRegistrationBean<TokenAuthenticationFilter>(filter);
registration.setEnabled(false);
return registration;
}
}
I can't find the error. I believe it is in the spring security config class. Can anyone help me?
P.S. My spring boot version is 2.4.5

multiple oauth2 services and configurations

I have an existing Spring application which is using configuration A extending
ResourceServerConfigureAdapter to secure APIs against an internal oauth service A.
I am trying to add another configuration B extending WebSecurityConfigurerAdapter which authenticates against an external oauth provider.
The aim is to continue with B determine authentication for /api/ related endpoints while A determines overall login to the web application.
Following is the existing code using ResourceServerConfigureAdapter:-
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Value("${oauth.clientId}")
private String clientId;
#Value("${oauth.clientSecret}")
private String clientSecret;
#Autowired
private RestTemplate restTemplate;
#Bean
public RemoteTokenServices remoteTokenServices() {
RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
remoteTokenServices.setRestTemplate(restTemplate);
remoteTokenServices.setClientId(clientId);
remoteTokenServices.setClientSecret(clientSecret);
remoteTokenServices.setCheckTokenEndpointUrl("srvc://myservice/api/v2/oauth/check_token");
return remoteTokenServices;
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(null);
resources.tokenServices(remoteTokenServices());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous()
.and().authorizeRequests()
.antMatchers("/api/secured/**").authenticated()
.antMatchers("/api/**").permitAll();
}}
Following is the code using WebSecurityConfigurerAdapter:-
#SpringBootApplication
#EnableOAuth2Client
#EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class DemoService extends WebSecurityConfigurerAdapter {
#Autowired
OAuth2ClientContext oauth2ClientContext;
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll().anyRequest()
.authenticated().and().exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and().logout()
.logoutSuccessUrl("/").permitAll().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
// #formatter:on
}
public static void main(String[] args) {
SpringApplication.run(DemoService.class, args);
}
#Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
private Filter ssoFilter() {
OAuth2ClientAuthenticationProcessingFilter googleFilter = new OAuth2ClientAuthenticationProcessingFilter(
"/login/google");
OAuth2RestTemplate googleTemplate = new OAuth2RestTemplate(google(), oauth2ClientContext);
googleFilter.setRestTemplate(googleTemplate);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(googleResource().getUserInfoUri(),
google().getClientId());
tokenServices.setRestTemplate(googleTemplate);
googleFilter.setTokenServices(
new UserInfoTokenServices(googleResource().getUserInfoUri(), google().getClientId()));
return googleFilter;
}
#Bean
#ConfigurationProperties("google.client")
public AuthorizationCodeResourceDetails google() {
return new AuthorizationCodeResourceDetails();
}
#Bean
#ConfigurationProperties("google.resource")
public ResourceServerProperties googleResource() {
return new ResourceServerProperties();
}
}
Both of them individually run fine but put together in the same project, problems start showing up. Everything compiles and runs fine but when I hit localhost:8080/ following happens -
The page loads fine but when I hit localhost:8080/login/google, it shows me a whitelabel error page like following
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Apr 06 13:22:27 IST 2017
There was an unexpected error (type=Not Found, status=404).
Not Found
I try to read a bit about ResourceServerConfigureAdapter vs WebSecurityConfigurerAdapter and I could only understand that there is some kind of filter-order that determines the priority of each configurer. But that hasn't helped me fix the issue. Any pointers?
Update:
There's another adapter for Swagger integration that is also part of the project.
#EnableSwagger2
#Configuration
public class SwaggerConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/docs", "/swagger-ui.html");
registry.addRedirectViewController("/docs/", "/swagger-ui.html");
registry.addRedirectViewController("/docs.json", "/v2/api-docs");
}
#Bean
public Docket swaggerSpringMvcPlugin() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("Spring Boot Service")
.description("Sample project documentation")
.contact("a#b.com")
.version("1.0")
.license("Apache")
.build())
.forCodeGeneration(true)
.ignoredParameterTypes(Principal.class)
.useDefaultResponseMessages(false)
.select()
.paths(documentedPaths())
.build();
}
private Predicate<String> documentedPaths() {
return or(
regex("/api.*"));
}
}
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
The OAuth2ClientAuthenticationProcessingFilter must after OAuth2ClientContextFilter, OAuth2ClientAuthenticationProcessingFilter will throw a redirect exception when the request is wrong(no code, etc...),
and the OAuth2ClientContextFilter will catch it and redirect to the userAuthorizationUri;
The BasicAuthenticationFilter is before OAuth2ClientContextFilter normal, , so you should change the order:
#Autowired
private OAuth2ClientContextFilter oAuth2ClientContextFilter;
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(oAuth2ClientContextFilter, ExceptionTranslationFilter.class)
.addFilterAfter(ssoFilter(), OAuth2ClientContextFilter.class);
}
UPDATE:
There is another place need to be updated, if you have multi chains, you should define the request match, the default value is '/**', and the default order of ResourceServerConfiguration is 3, the default order of WebSecurityConfigurerAdapter is 100, ResourceServerConfiguration has high priority.
// only handle the request start with `/api`
http.requestMatcher(new AntPathRequestMatcher("/api/**"))
http.anonymous()
.and().authorizeRequests()
.antMatchers("/api/secured/**").authenticated()
.antMatchers("/api/**").permitAll();
If you put the WebSecurityConfigurerAdapter before ResourceServerConfiguration by change the order, you should also config the WebSecurityConfigurerAdapter not to handler /api/**
// skip the request start with '/api'
http.requestMatcher(new RegexRequestMatcher("^(?!/api).*$", null))
.authorizeRequests().antMatchers("/", "/login/**", "/webjars/**").permitAll().anyRequest()
Update2:
.authorizeRequests().antMatchers("/", "/login**")
This matcher doesn't match /login/google, please update to /login/**, so it should be
.authorizeRequests().antMatchers("/", "/login/**").permitAll()

Spring Security OAuth2 and FormLogin in a one application

In my Spring Boot application I have RESTful API and MVC web dashboard for administration.
Is it possible to have both - Spring Security OAuth2 authentication/authorization(token based, stateless) for RESTful API and FormLogin(stateful) for Spring MVC web dashboard in a one application ?
How to properly configure it with Spring Boot ?
You need to configure your web security for form based login and Resource Server Security form REST Endpoints
Here is a working configuration that uses single sign on with an Authorization Server deployed separately.
#Configuration
#EnableOAuth2Sso
#EnableWebSecurity
protected static class ResourceConfiguration extends WebSecurityConfigurerAdapter {
#Value("${sso.url}")
private String ssoUrl;
#Autowired
private RedisConnectionFactory redisConnectionFactory;
#Bean
protected TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
#Bean
#Primary
protected ResourceServerTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager authenticationManager = new OAuth2AuthenticationManager();
authenticationManager.setTokenServices(tokenServices());
return authenticationManager;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.and().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.GET, "/static/**").permitAll()
.antMatchers(HttpMethod.GET, "/profile/**").permitAll()
.antMatchers(HttpMethod.GET, "/services/**").permitAll()
.anyRequest().authenticated()
.and().logout()
.invalidateHttpSession(true)
.logoutSuccessUrl(ssoUrl+"/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.deleteCookies("JSESSIONID").invalidateHttpSession(true)
.permitAll();
}
}
#Configuration
#EnableResourceServer
#Order(1)
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource-id");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new OAuthRequestedMatcher())
.authorizeRequests().anyRequest().fullyAuthenticated();
}
}
private static class OAuthRequestedMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader("Authorization");
boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
boolean haveAccessToken = request.getParameter("access_token")!=null;
return haveOauth2Token || haveAccessToken;
}
}

Resources