How do I use SSO in my Spring Security Application - java

#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
// .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.antMatchers("/", "/node_modules/**").permitAll()
.anyRequest().authenticated())
.oauth2Login()
}
}
With this code I can log in via oauth2 and a third party IDP. How can I get the application to check the IDP for a session on every request and then use it (SSO)?
I tried following:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
// .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.antMatchers("/", "/node_modules/**").permitAll()
.anyRequest().authenticated())
.oauth2Login()
.userInfoEndpoint()
.userService(oauth2UserService());
}
private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
DefaultOAuth2UserService delegate = new DefaultOAuth2UserService();
return userRequest -> {
OAuth2User oAuth2User = delegate.loadUser(userRequest);
// You can customize the OAuth2User object here, if needed
return oAuth2User;
};
}
}
I expected a redirect to the IDP to happen when the page is opened and then logs me in automatically. However, nothing happens.

Related

Spring Boot secure actuator endpoint with basic auth while securing other endpoints with Oath [duplicate]

I am trying to set up multiple WebsecurityConfigurerAdapter for my project where the spring boot actuator APIs are secured using basic auth and all other endpoints are authenticated using JWtAuthentication. I am just not able to make it work together, only the config with the lower order works. I am using Spring Boot 2.1.5.RELEASE
Security Config One with JWT Authenticator
#Order(1)
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/docs/**",
"/csrf/**",
"/webjars/**",
"/**swagger**/**",
"/swagger-resources",
"/swagger-resources/**",
"/v2/api-docs"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/abc/**", "/abc/pdf/**").hasAuthority("ABC")
.antMatchers("/ddd/**").hasAuthority("DDD")
.and()
.csrf().disable()
.oauth2ResourceServer().jwt().jwtAuthenticationConverter(new GrantedAuthoritiesExtractor());
}
}
The basic Auth config with username/password
#Order(2)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
/* #Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("user1")
.password(encoder.encode("password"))
.roles("ADMIN")
.build()
);
return manager;
}
#Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/actuator/**").hasRole("ADMIN")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("password").authorities("ADMIN");
}
}
I have been trying to make it work for many days but cannot make both of them work together. If i swap the order, only basic auth works and not the JWT Auth Manager.
I have gone through a lot of SOF Questions, like
[https://stackoverflow.com/questions/40743780/spring-boot-security-multiple-websecurityconfigureradapter][1]
[https://stackoverflow.com/questions/52606720/issue-with-having-multiple-websecurityconfigureradapter-in-spring-boot][1]
[https://github.com/spring-projects/spring-security/issues/5593][1]
[https://www.baeldung.com/spring-security-multiple-entry-points][1]
Nothing seems to be working, is this a known issue in Spring?
To use multiple WebsecurityConfigurerAdapter, you need restrict them to specific URL patterns using RequestMatcher.
In your case you can set a higher priority for ActuatorSecurityConfig and limit it only to actuator endpoints:
#Order(-1)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/actuator/**")
.and()
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}

Spring Security antMatcher with HttpMethod.POST does not work

Edit :
Thx Thomas Andolf !
It works when i use embended tomcat in springboot 'spring i launched on IntelliJ and the angular part with visual studio code.
But it does not work when i publish the war in provided tomcat on my raspberry pi...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests.antMatchers(HttpMethod.POST, "/rest/gender").permitAll()
.antMatchers(HttpMethod.POST, "/rest/login").permitAll()
.antMatchers(HttpMethod.POST, "/rest/names").permitAll()
.anyRequest().authenticated()
)
.httpBasic()
.authenticationEntryPoint(authEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
The angular part of the project is published in tomcat/webapps/ROOT.
The war is published in tomcat/webapps/baby-project-api.
I use tomcat/conf/Catalina/localhost/rewrite.config like this :
RewriteRule ^/rest/(.+)$ /baby-project-api/rest/$1
Original Question
I try to use Basic Authentication on an api with spring boot security and i need some path to be not secured.
POST /rest/login is not secured with the config,
GET /rest/gender is secured and that's what i want
Any idea why POST /rest/gender is still secured ?
There is my WebSecurityConfig :
#Configuration
#EnableAutoConfiguration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationEntryPoint authEntryPoint;
#Autowired
private IParentRepository parentRepository;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/rest/gender").permitAll()
.antMatchers(HttpMethod.POST, "/rest/login").permitAll()
.antMatchers(HttpMethod.POST, "/rest/names").permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.authenticationEntryPoint(authEntryPoint);
//.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
final List<Parent> parents = parentRepository.findAll();
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = auth.inMemoryAuthentication();
for (Parent parent : parents) {
mngConfig.withUser(User.withUsername(parent.getUsername()).password(parent.getPassword()).roles("ADMIN").build());
}
}
}```
POST /rest/login is not secured with the config,
GET /rest/gender is secured and that's what i want
Any idea why POST /rest/gender is still secured ?
can you please try doing it the way they actually do it in the documentation and see if it works.
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests.antMatchers(HttpMethod.POST, "/rest/gender").permitAll();
authorizeRequests.antMatchers(HttpMethod.POST, "/rest/login").permitAll();
authorizeRequests.antMatchers(HttpMethod.POST, "/rest/names").permitAll();
authorizeRequests.anyRequest().authenticated();
)
.httpBasic()
.authenticationEntryPoint(authEntryPoint);
}
After all, i did not find a great solution by this way.
i open all the api and restricted some parts with pre-auth :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll()
.and().httpBasic()
.authenticationEntryPoint(authEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
And on the controller :
#RestController
#PreAuthorize("isAuthenticated()")
#RequestMapping("/rest/gender")
public class GenderController {
[...]
// protected by the # on the class
#GetMapping(value = "")
public List<Gender> listerGender(final SecurityContextHolderAwareRequestWrapper request){
return genderService.listerGender(request);
}
#PreAuthorize("permitAll()")
#PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> creerGender(#Valid #RequestBody Gender gender){
return this.genderService.creerGender(gender);
}
I think we can make it cleaner but at least it works

Give simple HTTP 401 when trying to access some part of the web instead of redirect to login page

I've made a spring page using Spring Security. When I try to access any url inside this page, if the session is not set, it will redirect you to the login page: /login. This is fine, but now I've made a simple http rest api inside this web. What I want if I try to access any url inside /api/** just drop the 401, instead of sending a HTTP redirect to login.
I have made a Filter with preHandle:
public class BusinessKeyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()
&&
// when Anonymous Authentication is enabled
!(auth instanceof AnonymousAuthenticationToken)) {
// other stuf ....
}
} else {
if (request.getRequestURI().startsWith("/api")) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return false;
}
}
return true;
}
}
But in this case request URI is already /login
My configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().sessionManagement()
.invalidSessionUrl("/login?invalid")
.and().csrf().disable().formLogin()
.loginPage("/login")
.failureHandler(customAuthenticationFailureHandler)
.defaultSuccessUrl("/loggedIn")
.usernameParameter("email")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied")
;
}
I would recommend not mixing your previous security configuration with your new REST api config. You could do the following:
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Configuration
#Order(1)
public static class WebConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatchers("/web")
...
/* Your previous config would go here */
}
}
#Configuration
#Order(2)
public static class ApiConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatchers("/web")
... /* Your /api configuration goes here */
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
}
#Bean
AuthenticationEntryPoint customAuthenticationEntryPoint() {
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
}
}
}
This way, you could configure your rest api separately. Now you can have different a authentication entry point for your rest api. The fact is that you're most likely going to want to also provide a custom failure handler and success handler, which you can now do easily, and which will remain separate from the rest of your web application.

AbstractAuthenticationProcessingFilter is not firing before UsernamePasswordAuthenticationFilter

Hi to all Spring Experts!
I have an issue that I'm trying to solve for a while but i think that i have reached a dead end.
So basically what I need, is to configure my Spring-Security (in Spring-Boot) to have two authentication mechanisms (one for Legacy JSP pages and one for REST APIs). So I followed the following post:
multiple authentication mechanisms in a single app using java config
It worked fine with one LDAP authentication provider. But then I tried to extend my LDAP connection to also obtain a ticket from a third party service (that will be used for future connections to other services), and there I had a problem.
So I created a new Authentication Token, Filter and Authentication provider, but the default UsernamePasswordAuthenticationFilter is being fired first, no matter what I do.
I tried to follow this post How to configure a custom filter programatically in Spring Security? and saw that the problem might be in the fact that my filter was extending UsernamePasswordAuthenticationFilter. So I removed this and tried to have a simple AbstractAuthenticationProcessingFilter, still - no luck.
I think the problem is in my WebSecurity configuration. Currently, with the following code I'm gonna share, the REST Api authentication is returning 405 - method not allowed and the legacy Login is stuck in an infinite loop and crashes, even before I hit "Login".
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true) //Enables #PreAuthorize on methods
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPConfigurationBean ldapBean;
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//HERE GOES LDAP CONNECTION STUFF
// Add the custom LDAP + Token provider to the Authentication provider chain
auth.authenticationProvider(new TicketAndLDAPAuthenticationProvider(authenticator,authoritiesPopulator));
// Creating an LDAP provider using the authenticator and the populator.
auth.authenticationProvider(new LdapAuthenticationProvider(authenticator,authoritiesPopulator));
}
#Configuration
#Order(1)
public static class ConfigureFilters extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);
}
}
//Management Endpoints Authorization
#Configuration
#Order(2)
public static class EndpointsWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/manage/health")
.authorizeRequests()
.anyRequest().permitAll();
}
}
//API Authentication+Authorization
#Configuration
#Order(3)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private RestAuthSuccessHandler authSuccessHandler;
#Autowired
private RestAuthFailureHandler authFailureHandler;
#Autowired
private RestLogoutSuccessHandler logoutSuccessHandler;
private String LOGIN_PATH = "/api/authenticate";
private String USERNAME = "username";
private String PASSWORD = "password";
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http
.antMatcher(LOGIN_PATH)
.authorizeRequests()
.anyRequest().permitAll();
http
.antMatcher("/api/**")
//Stateless session creation - no session will be created or used by Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin().permitAll()
.loginProcessingUrl(LOGIN_PATH)
.usernameParameter(USERNAME)
.passwordParameter(PASSWORD)
.successHandler(authSuccessHandler)
.failureHandler(authFailureHandler)
.and()
.logout().permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
http
.authorizeRequests().anyRequest().authenticated();
}
}
//JSP Authentication+Authorization
#Configuration
#Order(4)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
/*Static content*/
http
.authorizeRequests()
.antMatchers("/css*//**").permitAll()
.antMatchers("/images*//**").permitAll()
.antMatchers("/scripts*//**").permitAll()
.antMatchers("/fonts*//**").permitAll()
.antMatchers("/login*").anonymous();
/*Login / Logout configuration*/
http
.formLogin()
.loginPage("/login.htm").permitAll()
.defaultSuccessUrl("/index.htm?name=******")
.failureUrl("/login.htm?error=true")
.and()
.logout().permitAll()
.logoutSuccessUrl("/login.htm")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
/*URL roles authorizations*/
http
.authorizeRequests().anyRequest().authenticated();
}
}
}
As you can see, I am trying to configure my filter in the "Configure Filters" method - but I have also tried to configure it inside the adapters, with / without a #Bean annotation - all with no luck.
Filter:
public class TicketAndLDAPAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TicketAndLDAPAuthenticationFilter() {
super("/*");
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//Save the password for later
String username = request.getParameter("username");
String password = request.getParameter("password");
TicketAndLDAPAuthenticationToken token = new TicketAndLDAPAuthenticationToken(username,password,null);
return token;
}
}
Edit: forgot to add to the filter:
if ( request.getParameter( "username" ) == null || request.getParameter( "password" ) == null ) == null ) {
return null;
}
Now I get 405 in both login mechanisms.
Token:
public class TicketAndLDAPAuthenticationToken extends UsernamePasswordAuthenticationToken {
private AuthTicket otp;
private String restoredPassword;
public TicketAndLDAPAuthenticationToken( String username, String password, RestAuthLoginTicket otp ) {
super( username, password );
this.otp = otp;
}
public AuthTicket getOTP() {
return otp;
}
public AuthTicket getOtp() {
return otp;
}
public void setOtp(AuthTicket otp) {
this.otp = otp;
}
}
Provider:
public class TicketAndLDAPAuthenticationProvider extends LdapAuthenticationProvider {
#Autowired
TokenUtils tokenUtils;
public TicketAndLDAPAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
super(authenticator, authoritiesPopulator);
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
TicketAndLDAPAuthenticationToken token = (TicketAndLDAPAuthenticationToken) super.authenticate(authentication);
token.setOtp(tokenUtils.getTicket(token));
return token;
}
#Override
public boolean supports(Class<?> authentication) {
return TicketAndLDAPAuthenticationToken.class.isAssignableFrom(authentication);
}
}
Thanks in advance!!
So I found the issue(s).
First of all, the right way to configure the authentication managers is not how I configured above because there is no antMatcher and this caused my resources and pages to be open to everybody.
Secondly, the problem that caused the infinite redirects and error 405 was that I haven't defined my filter to accept post.
After fixing that, my JSP login form and authentication mechanism worked fine, but the "/api" was redirecting to the login page instead of the resource.
What brings me to my final point - the http.formLogin() is creating a UsernamePasswordAuthenticationFilter. I have two of them - one for each login. So I had to add http.addFilterBefore() for each one of the logins, but with a different URL.
The "/api" url was again using the default redirects of Spring instead of what I have defined, so I had to override them.
These are the configurations and filters that are working for me:
Security Configuration:
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true) //Enables #PreAuthorize on methods
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPConfigurationBean ldapBean;
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//LDAP Stuff
TicketAndLDAPAuthenticationProvider ticketAndLDAPAuthenticationProvider = new TicketAndLDAPAuthenticationProvider(authenticator,authoritiesPopulator);
auth.authenticationProvider(ticketAndLDAPAuthenticationProvider);
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(authenticator,authoritiesPopulator);
auth.authenticationProvider(ldapAuthenticationProvider);
}
//Management Endpoints Authorization
#Configuration
#Order(1)
public static class EndpointsWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/manage/health")
.authorizeRequests()
.anyRequest().permitAll();
}
}
//API Authentication+Authorization
#Configuration
#Order(2)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private RestAuthSuccessHandler authSuccessHandler;
#Autowired
private RestAuthFailureHandler authFailureHandler;
#Autowired
private RestLogoutSuccessHandler logoutSuccessHandler;
private String LOGIN_PATH = "/api/authenticate";
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(LOGIN_PATH,authSuccessHandler,authFailureHandler), UsernamePasswordAuthenticationFilter.class);
http
.antMatcher("/api/**")
// Stateless session creation - no session will be created or used by Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.logout().permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
http
.authorizeRequests().anyRequest().authenticated();
}
}
//JSP Authentication+Authorization
#Configuration
#Order(3)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private String LOGIN_PATH = "/login.htm";
#Override
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(LOGIN_PATH), UsernamePasswordAuthenticationFilter.class);
/*Static content*/
http
.authorizeRequests()
.antMatchers("/css*//**").permitAll()
.antMatchers("/images*//**").permitAll()
.antMatchers("/scripts*//**").permitAll()
.antMatchers("/fonts*//**").permitAll()
.antMatchers("/login*").anonymous();
/*Login / Logout configuration*/
http
.formLogin()
.loginPage(LOGIN_PATH).permitAll()
.defaultSuccessUrl("/index.htm?name=******")
.failureUrl("/login.htm?error=true")
.and()
.logout().permitAll()
.logoutSuccessUrl("/login.htm")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
/*URL roles authorizations*/
http
.authorizeRequests().anyRequest().authenticated();
}
}
}
And the Filter:
public class TicketAndLDAPAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TicketAndLDAPAuthenticationFilter(String defaultProcessUrl) {
super(new AntPathRequestMatcher(defaultProcessUrl, "POST"));
}
public TicketAndLDAPAuthenticationFilter(String defaultProcessUrl, AuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler) {
super(new AntPathRequestMatcher(defaultProcessUrl, "POST"));
setAuthenticationFailureHandler(authenticationFailureHandler);
setAuthenticationSuccessHandler(authenticationSuccessHandler);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//Save the password for later
String username = request.getParameter("username");
String password = request.getParameter("password");
if ( username==null || password==null) {
return null;
}
TicketAndLDAPAuthenticationToken token = new TicketAndLDAPAuthenticationToken(username,password,null);
return token;
}
}

In Spring Oauth2 #EnableResourceServer how can I add role based request matchers

I am trying to give role based authorization for resources. It works with out roles if I do it like
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new OrRequestMatcher(
new AntPathRequestMatcher("/hello"),
new AntPathRequestMatcher("/user")
))
.authorizeRequests()
.anyRequest().access("#oauth2.hasScope('read')");
}
#Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.resourceId("openid");
}
}
If I use below method it won't work for test resources.
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.requestMatcher(new OrRequestMatcher(
new AntPathRequestMatcher("/hello"),
new AntPathRequestMatcher("/user")
))
.authorizeRequests()
.antMatchers("/test").hasRole("ADMIN")
.anyRequest().access("#oauth2.hasScope('read')");
}
It completely ignores token based authorization. How can I implement this? Another issue I am getting is if I remove requestMatcher block, Oauth client can not get the authorization code, after submitting user credentials to login form it reloads login page again. But with the previous block of code it works fine. What I am doing wrong here?
Here is my security configuration class
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.defaultSuccessUrl("/hello")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout");
}
}
When you use roles in spring you have to use prefix ROLE (for example ROLE_ADMIN) to make it work with default settings.

Categories