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**");
}
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!
I'm trying to use spring security to secure a rest/stateless api using JWT tokens. From the research I've been seeing, it involves turning off the spring security session management and then adding some custom filters to handle the user logging in as well as checking for the jwt token.
The problem I'm having is that once i add a filter, it's run on every instead of just the endpoints I want it on. I need to open up the login endpoint as well as a few others that will facilitate enrollment and reference data that doesn't need to be secured.
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/user").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(new StatelessAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}
}
All StatelessAuthenticationFilter does is print "in here". I'm only expecting to see that message print when you go to localhost:8080/api/order, but i see it show up when you go to localhost:8080/api/user.
Is there a way to get this behavior?
The way you configured, the HttpSecurity will be applied to all the URLs including the user endpoint.
authorizeRequests() .antMatchers("/api/user").permitAll() line won't prevent "user" endpoint from authentication filter being called.
It just says that any authenticated user can call it.
You need to apply the filter to "order" endpoint only. Like this:
http .requestMatchers().antMatchers("/api/user") .and() .authorizeRequests().
#tsolakp's answer sorta works for me. I ended up overriding the
configure(Websecurity) method though
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/user");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(new StatelessAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}
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();
}
I've a Spring Boot application providing secure Restful web services. It works well with following HttpSecurity configuration in it's own WebSecurityConfigurerAdapter class:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.antMatchers("/secure/**").hasRole(ROLE_XXX)
.anyRequest().authenticated().and().httpBasic();
}
This configuration forces all webservices to be authorized under /secure.
Now I want to add another a webservice, say /public/test, which can be called without any authentication. Any suggestions ?
Overriding void configure(WebSecurity web) method solved my problem:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/public/**");
}
I have a Spring Security version 3.2.3 application that listens to both HTTP and HTTPS. I want any request to the HTTP port to be redirected to HTTPS. How do I configure that using Java only?
Spring Security javadoc for HttpSecurity proposes the following solution (trimmed to the essential):
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) {
http.channelSecurity().anyRequest().requiresSecure();
}
}
However that doesn't work because HttpSecurity doesn't have method channelSecurity().
Replacing channelSecurity() with requiresChannel() in the code in the question appears to give the desired behaviour. The working code then looks as following:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) {
http.requiresChannel().anyRequest().requiresSecure();
}
}