Spring security 5 - UsernamePasswordAuthenticationFilter and basic authentication - spring

I'm trying to implement simple security for a small API school project and am a bit confused and overwhelmed. I followed
this blog post.
Everything works and I'm able to login and receive a jwt token. However login is currently performed by sending the username and password along with the URL as query parameters. That is of course something I would like to avoid.
I have tried adding httpbasic to the security configuration like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtAudience, jwtIssuer, jwtSecret, jwtType))
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers("/board/**").hasAnyRole("MEMBER", "BOARD")
.antMatchers("/members/**").hasRole("MEMBER")
.anyRequest().authenticated()
)
.httpbasic().and().
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Login however ceases to work and I constantly get an unauthorized while trying basicAuth with postman.
So my question is: How can I change the behaviour of these code snippets to accept basic authentication and not send user credentials by URL? Do I have to override the AttemptAuthentication method too?

Related

adding httpSecurity.csrf().disable() to spring security configuration is allowing unauthenticated endpoint calls

I have the following security configuration for my springboot project
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/test_url_1");
}
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/");
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
now I have another endpoint /test_url_2. Calling which should be redirected to error page for an unauthorized user. If am removing csrf().disable() its working fine and the request is going to default /error page. but on adding csrf().disable() ,I am noticing a very unusual behaviour. once another endpoint ex. /test_url_3 is being called with an jwt header for authorization, next time onwards the endpoint(/test_url_2) is blocked even for unauthorized user, i.e. instead of going to the error page its calling the end point.
I am still new to spring security and spring, and not sure if I am writing some configuration wrong, please help me with the issue.
I didn't get exact meaning of the following sentences:
I am noticing a very unusual behaviour. once another endpoint ex. /test_url_3 is being called with an jwt header for authorization, next time onwards the endpoint(/test_url_2) is blocked even for unauthorized user, i.e. instead of going to the error page its calling the end point.
If you didn't get what exactly CSRF I recommend watching this video: https://youtu.be/uzZzlar-iQI from 1:08:00. If you want to authenticate url1 and don't want to authenticate url2 try the following code instead of using anyRequest().
httpSecurity.csrf().disable()
.authorizeRequests()
.antMatchers('/ur1')
.authenticated()
follow through this URL for more info on CSRF: https://www.baeldung.com/spring-security-csrf

Configure spring security with oauth2/openid for session id but also access token

it is possible to configure spring with oauth2 to accept multiple login possibilities?
Currently I have it working with:
#Override
protected void configure(HttpSecurity http) throws Exception { // #formatter:off
http.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest()
.authenticated())
.oauth2Login(AbstractAuthenticationFilterConfigurer::permitAll)
.addFilterAfter(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()))
.oauth2ResourceServer().jwt();
} // #formatter:on
If one tries to access an authorize ressource, he gets redirected to a login page of an identity provider, logs in and then get a session id on the client side. The access token and the refreh token are held into memory on the server side.
But now I also want to use an access token to access ressources.
But when I do this, the security application context is just null.
What do I have to do?
I have searching in the doc but could not understand how to achieve this.
I would expect to just add in application.properties:
spring.security.oauth2.resourceserver.jwt.jwk-set-uri
And to add:
.oauth2ResourceServer().jwt() to my HttpSecurity but this does not do the work.
Found the answer, if Bearer is not set as prefix in the Authorization header when sending the token, then it will not be recognized.
Kind of normal since it is the standard...

Spring OAuth2 security concerns

I am currently implementing Authorization_Code type OAuth2 flow to have single-sign-on (SSO) on my website.
Here is my code that enables it.
#Override
protected void configure(final HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests()
.antMatchers("/login", "/authorize", "/error")
.permitAll()
.anyRequest()
.authenticated()
.and().formLogin().loginPage("https://sso.mywebsite.com").loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/success",true)
.failureUrl("/error").permitAll()
.and()
.csrf()
.disable();
// #formatter:on
}
My concern is described below.
To make a login request (with username and password), sso.mywebsite.com should make a POST request to my oAuth service - http://oauth/perform_login?username=USERNAME&password=PASSWORD.
I tried it with Postman and it works. However, isn't this a security problem to send plain username and password like above in query param? I thought exposing user credential in uri (query param) could get captured by various network sniffing tools.
Is there a way to do this in different method?
As long as you are using HTTPS, your query parameters will be secure.
I am unclear, why your SSO website should make a POST to that URL (and also, why instead of having a POST body, append the parameters via the url). Shouldn't it rather "redirect" to the login page/authorization server or is the code above from your authorization server? It was a bit unclear from your description.

Spring Boot Security without Login Form

I want to add security to a Spring Boot application so I thought about using Spring Security. My only problem is the Login Form, Is there some way to authenticate a User by reading the login credentials from a config file instead of letting someone type in the name and password? I want to do that because the application will be running on a Raspberry Pi. What would be the best approach for something like that?
You can use basic authentication and pass username and password in the header.
The configuration could look like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/dashboard/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic();
http.csrf().disable();
}
From the client you have to add the header:
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
The string behind Basic is the Base64 encoded username:password

how to implement a authentication with spring boot security?

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).

Resources