I'm developing a java spring mvc project. This is a part of my securityConfig class:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
....
.logoutSuccessUrl("/loginForm")
...
}
When a user logs out, spring redirects him to the loginForm page. But, I want to change this url, dynamically. In fact, I want to redirect users to different pages based on some conditions. How can I do this?
See LogoutSuccessHandler:
Strategy that is called after a successful logout by the LogoutFilter, to handle redirection or forwarding to the appropriate destination.
For Java Configuration see LogoutConfigurer#logoutSuccessHandler.
Your modified source code:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout().logoutSuccessHandler(myLogoutSuccessHandler);
}
Related
I've been trying to make an application with Spring Boot that uses Google as an identity provider for logging in.
The following configuration (using Spring Security) seems to work for this:
#Configuration
#EnableOAuth2Sso
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**","/callback/", "/error**")
.permitAll()
.anyRequest()
.authenticated();
}
}
However, I only really want to secure a small part of the website (e.g. everything under the /secured/ path).
So I thought changing the antMatcher that requests are authorized for would work for this:
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
antMatcher("/secured**")
.authorizeRequests()
...
When I try this the application still redirects me to /login, but it gives me a 404 on that page instead of redirecting me to google's servers.
I could of course add all public urls to the permitAll antMatcher, but that seems cumbersome to do everytime a new one is added.
Putting all public things on a /public** path is also not something I'd like to do since it'd look weird in the url
Could anybody shed some light on what is happening here or maybe offer alternative solutions?
Thanks in advance!
Spring 2.0.3.RELEASE
Goal: Implement Spring Boot Security (basic auth for starters) on all endpoints except /actuator/health, /actuator/info and /ping (a custom controller that just returns ResponseEntity.status(HttpStatus.NO_CONTENT).build()).
The below gives me a 401. Any combination seems to either give me complete anonymous access to all endpoints or 401 to all.
I've set the spring.security.user.name and ...password in application.yml and it is working correctly.
I've implemented...
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
super.configure(http);
// just trying to get health working for starters
http.authorizeRequests().antMatchers("/actuator/health").permitAll()
.anyRequest().authenticated()
.and().formLogin().permitAll();
}
}
The below seemed like it was restricted to Actuator's /health and /info endpoints, but instead is also opening up my custom /ping endpoint as well (it's not in this list).
http.requestMatcher(EndpointRequest.to("health", "info"))
.authorizeRequests().anyRequest().permitAll();
The issue ended up being a bug in Spring Tool Suite. Using Boot Dashboard with a Gradle project wasn't always picking up build output. It seems to be using a different directory and I cannot figure it out.
The HttpSecurity configuration that ended up working for me was:
#Override
protected void configure(final HttpSecurity http) throws Exception {
// #formatter:off
http.
authorizeRequests().
antMatchers("/ping", "/actuator/health", "/actuator/info", "/login").permitAll().
anyRequest().authenticated().and().
httpBasic().and().
// CSRF tokens for API access
csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// #formatter:on
}
Trying to get my WebSecurityConfigurerAdapter to put things in the "/secured/" context behind some filters, and then other URLs are not behind these filters.
Here's what I have so far, but everything is hitting the TokenFilter
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/secured/**").addFilterBefore(new TokenAuthenticationFilter(tokenAuthService, environment),
ExceptionTranslationFilter.class).
addFilterBefore(new RequestContentBufferFilter(), TokenAuthenticationFilter.class)
.antMatcher("/**").anonymous()
.and().csrf().disable();
}
Any help?
I ended up using the WebSecurity context to add a blacklist of endpoints for security to ignore like this:
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/metrics**")
.antMatchers("/health**")
.antMatchers("/logfile**")
.antMatchers("/systemcheck**");
}
I'm taking my first try on the Spring Security and really got stuck on such a task: i have a default webpage, which should be defaulty non-authenticated, and i have a batch of controller calls, which i want to secure with a PreAuthorized annotation. The basic idea is, that i want to disable the default "redirect to login page", but still have the opportinity to operate the Spring Security's method security complex.
I'm using a java configuration, which looks like:
#Configuration
#EnableWebSecurity
public class SpringWebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/res/**"); // #3
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().anyRequest().permitAll();
}
}
I know(or seem to understand) that by this point all of my calls should be permitted(have been sitting over this for the past two days, and clearly running out of ideas).
The Controller's method, which i want to secure, is:
#PreAuthorize("hasRole('ADMIN')")
#RequestMapping(value="/admin", method = RequestMethod.GET)
public String getAdminPage(Model model){
return "admin";
}
I know that i can use antMatcher to add "/**/admin" and authorize the calls to the specific url, but the general idea is:
Disable the "go to login page" on the root(and other random controller mappings).
Do a manual ajax based authentication from a ajax drop down(or something).
When a random non-autherised user bumps in a page, which has a #PreAuthorized on a Controller, then, and only then, he should be redirected.
UPD: the basic question is to invoke the redirect to login page only on access denied scenario, allowing the anonymous role for basic site view's and calls.
Answering my own question(maybe not as clean as it should look).
You can config the Spring Security Http Security so it wont ask to login on every page:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().anyRequest().permitAll();
To enable the method security(the PreAuthorize("hasRole('ADMIN')") and ect), you need to add an annotation:
#EnableGlobalMethodSecurity(prePostEnabled = true)
after which you need to add to the HttpSecurity object something to catch the exceptions of "Access Denied and ect" (found this on some other stackoverflow question thread):
http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
if (authException != null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print("Unauthorizated....");
}
}
});
And now you can secure your controller and other components with #PreAutherized. Hope this will help someone.
But there still remains one thing - when the user is unauthorized and i try to reach some preAuthorized page, the above mentioned exception handler is invoked, returning the "Unauthorized..." message. But when the user is authorized and i try a page with a diffirent preAuthorized role, i get the default 403 Access Denied.
I've followed this and this tutorial to create a skeleton of an Angular.JS application with a Java-based backend. Its code can be found here.
It has authentication - at the start Spring boot writes to the console a random password, which you can use to login to the started application. User name is user and the password is printed in the console at the start:
Now I want to have several user accounts with fixed passwords (it's OK, if they are hardcoded).
How can I do this in that application without breaking compatibility with AngularJS?
I suppose that I have to modify SecurityConfiguration in UiApplication and use something like
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
as explained here, but I'm not sure that it won't break AngularJS.
That's the solution:
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfiguration extends
WebSecurityConfigurerAdapter {
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1")
.password("password1")
.roles("ADMIN")
.and()
.withUser("user2")
.password("password2")
.roles("USER");
}
As long as you don't change the authentication scheme (i.e. BASIC, FORM etc.), AngularJS doesn't care about how you manage the user accounts in the backend. Of course if you would have used a fixed user and password and have it hardcoded in the AngularJS code, you would have to change this.
It wouldn't break the angular compatibility. But in addition to the code change you mentioned, you would also need to make sure that you are allowing access to /login URI anonymously. Change in your overloaded configure method would also be required, something as follows:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/login.html").permitAll()
.antMatchers("/index.html", "/home.html").authenticated()
.antMatchers("/index.html", "/home.html").hasRole("USER")
.anyRequest().authenticated();
}