I'm working with Spring Boot 1.4.2.RELEASE, Spring Security 4.1.3.RELEASE, and Java 8.
For the security configuration I have the following class:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/assets/**", "/logout", "/login");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement() // 1
.sessionFixation() // 2
.migrateSession() // 3
.maximumSessions(1) // 4
.maxSessionsPreventsLogin(true).expiredUrl("/login").and() // 5
.invalidSessionUrl("/login") // 6
.and() // 7
.authorizeRequests()
.antMatchers("/app/**").authenticated()
.antMatchers("/about").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/auth").permitAll()
.defaultSuccessUrl("/app/index", true)
.failureUrl("/login?error")
.usernameParameter("uid")
.passwordParameter("pwd").and()
.logout()
.permitAll()
.invalidateHttpSession(true)
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login").permitAll()
.clearAuthentication(true).and()
.exceptionHandling().and()
.csrf().disable()
.headers().frameOptions().disable()
.cacheControl().and();
}
}
When try access to "/about" (permit all everyone), redirects me to "/login". I try it a second time and now it allows me to access "/about".
I have changed the authorization order of requests in the configuration class but don't works. When I delete the lines of sessionManagement (1 to 7), everything works normally.
Do I need any extra configuration?
When you are testing this, did you clear your browser's cookie with regard to your testing site? The session management filter sets a jsessionid cookie, which gets sent back. Your browser has no idea that you reset your server, so thinks the cookie is just fine, and you send back an invalid session.
You may want to take a look at your session creation policies to see whether or not it suits your purpose.
Related
My aim is to add security class to my Java project except paths like "api/public/*".
When I request in POSTMAN
http://localhost:8080/api/public/signup
with a json body, I get 401. Here's my security class which permits all matchers of api/public/*:
What am I missing?
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.cors()
.and()
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
// don't create session
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated();
// Custom JWT based security filter
JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil);
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// disable page caching
httpSecurity
.headers()
.frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank.
.cacheControl();
}
#Override
public void configure(WebSecurity web) throws Exception {
// AuthenticationTokenFilter will ignore the below paths
web
.ignoring()
.antMatchers("/api/public/*");
}
Mvn clean solved my problem. It seems build somehow stuck in a previous state.
mvn clean
I'm new to Spring Security, I'm trying to create a login form with Spring Security.
This is the required scenario:
1) users log into the app with username - password (please note that I'm using the default loginpage provided by spring Security)
2) if the login is OK, the user go to eventList.jsp
3) if the login is KO (wrong credentials) an error is shown
My WebSecurityConfigurerAdapter configurations:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("amdin").password("111111").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().defaultSuccessUrl("/eventList");
}
Error 1: if I insert the right credentials I don't see /eventList, but i receive a 404 (/spring-security-helloworld-annotation/WEB-INF/pages/login.jsp). Why I am not redirect to /eventList? (pheraps because /eventList accept only GET in my RequestMapping annotation?
#RequestMapping(value = {"/eventList"}, method = RequestMethod.GET)
Error 2: if I try to "manually" go to /eventList, by adding "eventList" to the end of the URL in my browser, I can access to the requested page without performing the login operation!!! THe only URL that I want to be accessible without performing the login operation is the login page itself!!!
The line.anyRequest().authenticated() should not allow all this!!!
How could I obtain what I desire?
TY in advance
The correct security chain looks the following:
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/eventList")
.permitAll()
.and()
.logout()
.permitAll();
you forgot the permitAll() statement as well defining the loginPage()
Hope it helps! Drop me a pm if you need further help with it.
I have created a Spring Boot app and I have my front-end app in the /resources/static folder.
For the routing, I am using Angular JS UI Router library.
I have defined a route, which I only want to be accessed by the admin and now I am trying to secure it using Spring Security.
Here is my WebSecurity Configuration class:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN")
.and()
.formLogin()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/member", "/member/**").permitAll()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/**/*.css",
"/**/**/*.js",
"/**/**/*.html",
"/**/**/**/*.css",
"/**/**/**/*.js",
"/**/**/**/*.html",
"/**/**/**/**/*.css",
"/**/**/**/**/*.js"
).permitAll()
.antMatchers("/auth/**", "/member/**", "/account/**").permitAll()
.and()
.csrf().disable();
}
}
The route I am trying to secure can be accessed through http://localhost:8080/#/admin.
However, whenever I am accessing that route, no login is requested and the page can be viewed by anyone.
Is it there another approach I should follow?
The URL: http://localhost:8080/#/admin is mapped to / in your permitAll list instead of the /#/admin rule, since #/admin part is just URL fragment, and usually not the business of the server side.
You have to define an API between your frontend and backend. Usually in RESTful web services form, and serve at /api/* path. Secure the path, and let your frontend talk to your backend through those APIs only.
It is eaiser to fix your issue,
Update
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN")
To
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN").anyRequest().authenticated()
For every matchers, you always need with permitAll() or authenticated() for it.
I'm creating a Spring boot application with Spring Web,Spring Security and Spring social. The application contains rest services that utilizes basic authentication for security. I"m trying to configure Spring to make the application stateless, however when I use the browser to make requests to the web services the browser prompts for user credential but all prior request use the same user credential because of session creation. I have configured the application to stop this from happening but still having the problem. \
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#override
protected void configure(HttpSecurity http) throws Exception{
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**")
.hasRole("USER")
.andBasic();
}
#override
protected void configure(AuthenticatioinManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("some#gmail.com")
.password("12345")
.role("USER");
}
}
What should I change or add to get this functionality.
Spring security is based on something called the SecurityContext. This something is a ThreadLocal, e.g only exists on one thread at a time. Each request will be on it's own thread and will have no access to any protected resource unless that SecurityContext is set to contain the appropriate roles. So even though you just logged in, which behind the scenes inserted roles into the SecurityContext, that security context is gone just as though it had been a different user. Tokens are how you want to deal with this issue. Or base64 encode your username and password into every request, whatever floats your boat.
Look at this:
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() //allow CORS option calls
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
I've been playing around with Spring for the last few days and things are getting to be fun. I'm working with security right now and I've run into a slight snag. Basically, I want the authentication to happen via an API call rather than a form. Is there a neat way to do this?
I've extended the WebSecurityConfigurerAdapter like so -
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/openapi/**").hasRole("USER")
.anyRequest().authenticated();
http
.formLogin()
.defaultSuccessUrl("/hello")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
authManagerBuilder.inMemoryAuthentication()
.withUser("manager").password("password").roles("MANAGER");
}
}
Is there a way to pick up the the usernames and passwords from a database and can I perform the authentication with an API call?
Spring Security 3 database authentication with Hibernate
This seems promising. It needs a custom authentication manager created.
You can use jdbc authentication with Java configuration as described in the reference http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#jc-authentication-jdbc