how to implement a authentication with spring boot security? - spring-boot

i am using spring boot. i want to post a username and password params to login, and if login success then return a token. after, i will use the token to judge login status. here is my security configure code. but i don't konw where to write the login authentication logic code.
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.fullyAuthenticated()
.and()
.formLogin()
.loginPage("/user/unlogin")
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/user/login")
.antMatchers("/user/logout")
.antMatchers("/user/register");
}
}
==========================
thank you !

There's always more than one way to do something with Spring. There is a happy path (probably) with Spring Boot, and you seem to have started on it. Note though, if you want Boot to provide some default behaviour, then don't use #EnableWebSecurity (as advised in the user guide). The web-secure sample has an example you can follow.
If you use formLogin() the default login URL is /login (not /user/login), so you should be able to post the username and password to that endpoint to authenticate. Don't add /login to the unsecured paths using web.ignoring() or Spring Security will never process it. When you post to /login you get back a JSESSIONID cookie. That's your authentication token, and it expires when the session expires in the server (30min by default, but easily configurable). Include it in future requests for secure resources - some HTTP clients will even do that for you (like a browser does).

Related

Springboot filter executed in case of permitAll urls as well

I am new to springboot and trying to implement security where no filters are applied to my login, signup and home urls.
I am using springboot 2.7.1
I am expecting antMatchers("/**/signup").permitAll() to remain free of any security filter.
Upon debugging, I found that my signup url was being hit and user details were saved, but my AuthorizationFilter was also being executed .
This is my SecurityFilterChain :
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder=http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.userDetailsService(userLoginService).passwordEncoder(bCryptPasswordEncoder);
AuthenticationManager authenticationManager=authenticationManagerBuilder.build();
http.csrf().disable().authorizeHttpRequests()
.antMatchers("/**/login").permitAll()
.antMatchers("/**/signup").permitAll()
.antMatchers("/home/**").permitAll()
.anyRequest().authenticated().and()
.addFilter(getAuthenticationFilter(authenticationManager))
.addFilter(new AuthorizationFilter(authenticationManager))
.authenticationManager(authenticationManager)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
I don't understand why is it happening this way.
When you use permitAll() you are not disabling the filters, you are just specifying that you do not want to apply any authorization checks for that RequestMatcher. All the filters will still work.
The AuthorizationFilter will be invoked but since you configure permitAll() for that endpoint, it will always grant access.

Keep session id in case of presence of special parameter in request. Spring Security

Does anybody know if there any way to configure Spring Security in the way that it doesn't change session id if there is some parameter in the request.
For example:
somesite.com/home.jsp?password=encrypted- change session id after
authentication
somesite.com/home.jsp?password=encrypted& keepsessionid - don't
change session id after authentication
I was thinking about filter chain, maybe removing conditionally SessionManagementFilter, but not sure if this is a proper way, and even if this will be working
For someone with the same question. I found the answer. Different session management strategy can be achieved by using multiple http security configuration (inner classes of main security classes). The special case http security configurer should be adjusted to some special request
#Configuration
#Order(1)
public class SpecialCaseSessionHandlingConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(request -> Check1(request))
.authorizeRequests()
.anyRequest().authenticated();
}
}

Getting [invalid_id_token] Missing (required) ID Token in Token Response for Client Registration: github

I'm using SpringBoot and Oauth2 to authenticate on my application, using github for now.
If I use the scope oidc on application.properties the process works fine and github is used for he login.
My issue is that I want/need to use scope openid to get the id_token. When I change my application.properties to
spring.security.oauth2.client.registration.github.scope=openid
I start getting this error as response from login:
[invalid_id_token] Missing (required) ID Token in Token Response for Client Registration: github
I still get the http://localhost:8080/login/oauth2/code/github?code=ABC&state=CDE but right after that, the error shows up.
My security class is:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.oauth2Login()
;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("springuser").password(passwordEncoder().encode("spring123")).roles("USER")
.and()
.withUser("springadmin").password(passwordEncoder().encode("admin123"))
.roles("ADMIN", "USER");
}
Any clue on what I should look to?
Thanks in advance
This
spring.security.oauth2.client.registration.github.scope=openid
activates OpenID Connect authentication, that's built on top of Oauth2.
But that's no longer just Oauth2, as it requires that token.
If Oauth2 is what you want, just remove the above line.
Yes it's just confusing, and that's probably why folks avoid OIDC.
I got it working!
Turns out the issue wasn't on the code. Problem was somehow on the github oauth2 credentials. When I used a token/secret generated by Google Credentials I didn't have to change anything else besides the application.properties.
The mistery about github login still remains, since there's not much data on the token register to be changed.

Is it possible to implement only XSS prevention in Spring security and leave everything else open?

I'm working on a project where the OAuth2 implementation has not yet been consolidated, but I have been requested to investigate XSS prevention on the platform. Since the security concern is a known vulnerability, can Spring Security be in place to prevent XSS only and disable any form of authorization and authentication?
Yes, though there may be some things that you will still want, like Spring Security's application firewall.
By default, HttpSecurity will add http basic, form login, CSRF protection, and various security headers, but these can all be configured. The following leaves only the X-XSS-Protection header in place:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) {
http
.csrf().disable()
.headers()
.defaultsDisabled()
.xssProtection()
}
}

Spring boot actuator secure services does not work fine

I an Trying to secure spring actuator services /manage context path when calling for example:
http://localhost:9091/manage/metrics
with this config in my yalm.properties
management:
port: 9091
address: 127.0.0.1
context-path: /manage
security:
enabled: true
role: ADMIN.
Git branch with security actuator service layer
but access to every service is still free.
Spring security config:
'#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/pizzas","/info","/addPizza").hasAnyRole("USER","ADMIN").and().authorizeRequests().antMatchers("/users","/addUser").hasRole("ADMIN").and().authorizeRequests().antMatchers("/static/**","/logout","/login").permitAll();
http.formLogin().loginPage("/login").failureUrl("/login?error").permitAll();
http.logout().logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll();
http.sessionManagement().maximumSessions(1).
expiredUrl("/?expired").maxSessionsPreventsLogin(true).and()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}
/**
* Configure global security with Bccyptenoncder and custom userDetailService with Spring Security
* #param auth
* #throws Exception
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder());
}
/**
* Bcrypt password encoding configuration, more info at http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt
* #return
*/
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
'
Spring boot team has resolved me this issue. I share the solution here:
Same Origin Policy
You cannot use the login page from your main Spring Application within actuator security. The reason is that the cookie is going to be associated with the domain + port + context path of the application. This is part of the Same Origin Policy
This means if you sent the user to localhost:9090/pizza/login and authenticated, when you visited localhost:9091/manage/ the JSESSIONID cookie would not be submitted to the management application which means you would not be seen as authenticated.
In order to authenticate across domains (i.e. different ports in this case) you would need some single sign on (OpenID, CAS, SAML, etc) mechanism.
Mapping a Login Page in the Management Application
In order to use this configuration you would need to setup a login page within the management application. To do this you would just need to return an HTML form when /login is requested. However, I'm not really certain how you would do that within the Boot management application. Perhaps #philwebb or #dsyer can elaborate on how one would do that.
Distinct Security Configuration for the Management Application
Alternatively you could create separate security configuration for the management application that allows authenticating with Basic Authentication. To do this you would create another Security Configuration that looks something like this:
#Order(0)
#Configuration
public class ManagementSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.requestMatchers(request -> "/manage".equals(request.getContextPath()))
.and()
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
This would make sure that if the context root is "/manage" that this security configuration is used. A few points of interest:
#Order(0) makes sure the configuration occurs before your other security configuration since by default any subclass of WebSecurityConfigurerAdapter will be ordered at 100. This is important because only the first WebSecurityConfigurerAdapter is used (similar to the authorizeRequests() matchers).
The request matcher is using a lambda for matching on the contextPath. I had thought there was a better way to distinguish Spring Boot application from the main application, but it does not appear that is the case. Perhaps #dsyer knows how this should be done.
NOTE
You can rewrite your configuration much more concisely as:
http
.authorizeRequests()
.antMatchers("/pizzas","/info","/addPizza").hasAnyRole("USER","ADMIN")
.antMatchers("/users","/addUser").hasRole("ADMIN")
.antMatchers("/static/**","/logout","/login").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/?logout")
.deleteCookies("remember-me")
.permitAll();
You might consider reading Spring Security Java Config Preview: Readability for details on how to format the configuration to better read it too.

Resources