I am using the following Java Config with Spring Security:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
Based on this configuration, all requests are authenticated. When you hit a controller without being authenticated, the AnonymousAuthenticationFilter will create an Authentication object for you with username=anonymousUser, role=ROLE_ANONYMOUS.
I am trying to provide anonymous access to a a specific controller method and have tried to use each of the following:
#Secured("ROLE_ANONYMOUS")
#Secured("IS_AUTHENTICATED_ANONYMOUSLY")
When the controller methods get invoked, the following response is given:
"HTTP Status 401 - Full authentication is required to access this resource"
Can someone help me understand why we are receiving this message and why ROLE_ANONYMOUS/IS_AUTHENTICATED_ANONYMOUSLY don't seem to work using this configuration?
Thanks,
JP
Your security configuration is blocking all unauthenticated requests.
You should allow access to the controller with
.antMatchers("/mycontroller").permitAll()
See also:
http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/
Related
I have backend in spring-boot, exposing REST API, and i have SEPARATED front end in react.
I want to use spring security to secure my back end, and i want to keep spring authentication chain. However, when i use configuration such as:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.cors().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/newUser").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.and()
.formLogin().pertmitAll();
}
This generates /login endpoint and every request that is not authorized will get redirected to login page. However spring generates this /login login page and as i said i have my own stand-alone fornt-end in REACT, so i do not want spring to generate this page, i want it to tell my client to redirect to /login. If i disable formLogin
.formLogin().disable()
then i also lose my /login POST endpoint, and springs default authentication process.
Is there a way to keep to /login POST endpoint but remove the login page and let my frond-end client to redirect.
Thanks for help!
I agree with Toerktumlare 100%. You really should use the default implementations that Spring Security Framework offers and if you really need to add additional configuration that cannot be passed by values, then you should extend the original Spring Security Class.
In this case, you just have to specify the endpoint where your login page is:
.formLogin()
.loginPage("/yourLoginPage.html")
.loginProcessingUrl("/doLgin")
.defaultSuccessUrl("/yourHomePahe.html", true)
When you use the GET method, you will get html page. As I understand you need POST API call, Post API call to get JWT access_tocken and refresh tocken
you can use "/login" as API in post call to send a username and password; in response, you will get a token or anything that you send after successful authentication.
I have override the configure method of WebSecurityConfigurerAdapter class as:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
I have APIs as /admin, /admin/user, /admin/user/test. When i login as admin i can access all the three URLs. I just wanted to know the difference between '/admin/**' and '/admin',
In case of /api/**, hasRole(...) will be authorized to all the requests that starts with the pattern /api.
And in case of /api, hasRole(...) will be authorized to only one request i.e. /api
In the above question only the '/admin' request is authorized to 'ADMIN' role. We can also access the other URLs because other URLs just need to be authenticated ignoring the role. We can also access the '/admin/user' or '/admin/user/test' while logging with user. If we have used antPattern as '/admin/**', then we won't be able to access those APIs through the session of user.
I am new to Spring Security and i was about to post the question but after spending some time, i came to know a little about it, so i also included my understanding for suggestions.
I have a spring boot oauth2 service working locally. But when I deploy this to Heroku it fails with a 401.
So on my local system I go to the UI and I have no valid JWT so it does a redirect to:
localhost:8080/api/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient
The spring gateway routes to my auth service, localhost:8066/auth/login. I login with valid username/password and it routes to localhost:8066/auth/validate, which gives this response header:
Location: localhost:8066/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient
It redirects to:
localhost:8066/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient
...and the response header location on that call is: localhost:4200#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.etc...
It routes back to the UI and I have the access token. Everything works as expected.
I do this in Heroku I get to this auth/validate step abc-authserver.herokuapp.com/auth/validate, and the response header location is Location: abc-authserver.herokuapp.com/auth/.
I am expecting it to be:
abc-authserver.herokuapp.com/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=https%3A%2F%dummyui&scope=webClient
but its not so it routes to abc-authserver.herokuapp.com/auth/ and I get a 401.
Why is Heroku dropping my response_type, client_id, scope and redirect_uri information? Why is it changing the Location in the response header when I am validating? The logs show that my username and password are correct and I have the information. It just has no idea where to go.
This is my resourceConfig in the authservice...
#Configuration
#EnableConfigurationProperties
public class ResourceConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER).and()
.authorizeRequests()
.antMatchers("/api/**", "/auth/**", "/oauth/**", "/login", "/validate").permitAll()
.and().formLogin()
.loginPage("/login").loginProcessingUrl("/validate")
.and()
.logout().and().httpBasic().and().authorizeRequests().anyRequest().authenticated();
}
}
I need to figure out how to not lose the redirect information. I can provide any additional information needed. I am wasting tons of time trying to figure this out. I would appreciate any input. Thanks.
My application has an authenticated admin area. My problem is that it also requires authentication for the login page (although it's marked as either "anonymous" or "permitAll" - I've tried both).
My configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin/**")
.authorizeRequests()
.antMatchers("/admin/login.html", "/admin/logout.html").permitAll() //"anonymous()" has same result
.antMatchers("/admin/**").hasAnyRole("ADMIN", "PUBLISHER")
.anyRequest().authenticated()
.and()
.addFilter(preAuthenticationFilter())
.addFilter(adminExceptionTranslationFilter())
.csrf().disable()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout.html"))
.logoutSuccessUrl("/index.html")
.invalidateHttpSession(true);
}
The only thing I could think of that might be the culprit is the preAuthenticationFilter which extends the AbstractPreAuthenticatedProcessingFilter class (the authentication is smart card based and that class extracts the credential from a certificate sent by the browser). I'm guess that maybe because it's a type of preAuthenticated filter, then maybe Spring runs it before any request - thus prompting the authentication request in the browser (even if the accessed page "/admin/login.html" doesn't require authentication).
So my question ultimately is how do I actually disable authentication for the login page? As far as I can tell from the documentation, the antMatchers are configured correctly.
It was a proxy problem. The code in question is correct.
I read a lot of manual of how to configure spring security, but still stuck with configuration.
So i want to configure rest calls and other http calls. As i understand i can create urls like /server/** - for web application and /rest/** - for rest application. For any call of web application urls i want to create a login page (when user not authenticated), but for rest app, i want to fire Unauthorised code.
I do it with spring annotations by extend WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/").access("hasRole('ROLE_USER')")
.antMatchers("/server/*").access("hasRole('ROLE_USER')")
.and()
.formLogin().loginPage("/login").permitAll().failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and()
.exceptionHandling()
.accessDeniedPage("/accessDenied");
}
for server it works fine, but if i try to add /rest here when i try to call /rest/[something] (in browser), it always forwards me to /login page.
I don't understand why and it is break my mind.
Thanks for any helpful responses.
You have this:
.antMatchers("/").access("hasRole('ROLE_USER')")
.antMatchers("/server/*").access("hasRole('ROLE_USER')")
.and()
.formLogin()
means / access need ROLE_ACCESS and for authentication, direct to formLogin
You need multiple authentication conf.
see http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/
And in one of them you need something like this
http
.antMatcher("/rest/**")
.exceptionHandling().authenticationEntryPoint(new AccessDenyEntryPoint()).and()
.authorizeRequests().antMatchers("/spring/**").denyAll();
You have to add one more .antMatchers("/rest/*").permitAll() if you don't want to validate your rest urls.