Multiple antMatchers in Spring security - spring

I work on content management system, that has five antMatchers like the following:
http.authorizeRequests()
.antMatchers("/", "/*.html").permitAll()
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/admin/login").permitAll()
.antMatchers("/user/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
which suppose to mean that the visitors can see all site at root path (/*), and users can see only (/user), admin can see only (/admin), and there are two login pages one for users and another for admin.
The code seems to work fine, except the admin section - it doesn't work but return access denied exception.

I believe that the problem is in the order of your rules:
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/admin/login").permitAll()
The order of the rules matters and the more specific rules should go first. Now everything that starts with /admin will require authenticated user with ADMIN role, even the /admin/login path (because /admin/login is already matched by the /admin/** rule and therefore the second rule is ignored).
The rule for the login page should therefore go before the /admin/** rule. E.G.
.antMatchers("/admin/login").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")

Related

GWT Keycloak logout redirection

So I'm struggling with the integration between Keycloak and GWT.
I do have a AsyncCallBackHandler where I do handle the 403 exception and then redirect to logout when session expires.
My problem is the following :
I tried the Window.Location.replace("sso/logout") which gives me 502 for some reason when redirecting to login, but works fine with the logout button
I tried the Window.Location.replace("http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri"), it redirects fine to login page, but the problem is when logging in again, I get a weird behaviour like a file gets downloaded and login button gets disabled...
Not sure what I'm doing wrong, any help would be appreciated.
if (ex.getStatusCode() == HttpStatus.SC_FORBIDDEN) {
Window.Location.replace("sso/logout");
}
Configuration on Spring security side is the following :
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/sso/login");

Spring MVC based application is not landing to default success url while trying to access it using https url but working fine on http based url

While running the spring mvc based application on http, it is working fine but once the application is moved to https based configuration, we are not able to get successful landing url page. The url which are non authenticated is working fine but the authenticated urls are not reachable even after providing correct login credentials.
Please help me with the missing configurations/issues to resolve this problem.
The application is deployed over Jboss server.
Below are the configurations done as part of application.
protected void configure(HttpSecurity http) throws Exception {
System.out.println("I am configure");
http.csrf().disable();
// The pages does not require login
http.authorizeRequests().antMatchers("/login", "/logout", "/resetPassword", "/forgotPassword", "/change-password", "/confirm-account", "/registerPage", "/registerwithemail", "/resources/**", "/logoutSuccessful", "/login/**").permitAll();
http.authorizeRequests().antMatchers("/**").authenticated();
http.authorizeRequests().antMatchers("/home").authenticated();
http.authorizeRequests().antMatchers("/").authenticated();
// /userInfo page requires login as USER or ADMIN.
// If no login, it will redirect to /login page.
http.authorizeRequests().antMatchers("/userInfo").access("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')");
// For ADMIN only.
http.authorizeRequests().antMatchers("/admin").access("hasRole('ROLE_ADMIN')");
// When the user has logged in as XX.
// But access a page that requires role YY,
// AccessDeniedException will throw.
http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/403");
http.headers().frameOptions().sameOrigin();
// Config for Login Form
http.authorizeRequests().and().formLogin()//
// Submit URL of login page.
.loginPage("/login")//
.loginProcessingUrl("/j_spring_security_check") // Submit URL
.defaultSuccessUrl("/home", true)// userInfo (Changed to) home
.failureUrl("/login?error=true")//
.usernameParameter("username")//
.passwordParameter("password")
// For Remember-me
.and().rememberMe().rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400)
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/logoutSuccessful").invalidateHttpSession(true).deleteCookies("JSESSIONID", "remember-me");
}
if there is any channel security for http/https is required, please let me know about the configurations as I'm also traversing internally to different module using ip and port based http url.

Spring Boot/Security - Custom 404 page

I have created a custom 404 error page in my Spring Boot app, I also use Spring Security and I have an authentication entry point with a number of authorised URL's (error page included in that list).
What I'm finding is that if I enter a URL that doesn't exist the authentication entry point intercepts the request as it isn't an authorised URL and I end up back at my login page instead of the custom 404 error page. Any ideas?
Basic example of what I have in the security config
http
.csrf().disable()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
.and()
.authorizeRequests().antMatchers("/login", "/error-404")
Here is what Spring Security will do when you invoke /invalid-url
If /invalid-url is secure (default)
Store the request (/invalid-url -> session)
Invoke authentication entry point
Redirect to /login
User will authenticate
Upon successful authentication, redirect to stored request /invalid-url
Page not found - redirect to error handler
If /invalid-url is not secure
Page not found - redirect to error handler
So basically, you'd need to declare all your non secure URLs if you want the second flow, directly go to 404 page
.mvcMatchers("/login", "/error-404/**", "/invalid-url/**").permitAll()
Obviously doing this:
.anyRequests().permitAll()
as the last statement will solve your use case, it is also dangerous. You have then explicitly map out any endpoint that must be secured. And if you forget one, that endpoint will be left exposed.

Disabling spring security for google login in application

I have a spring boot application with default level spring security and i am using auth.userDetailsService(customuserservice) for the user authentication part. Apart from that we are using Google login button. My configuration file is
`http
.authorizeRequests()
.antMatchers("/","/securitylogin").permitAll()
.antMatchers("/SecondMainPage")
.hasAnyRole("SUPERADMIN","ADMIN","USER")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/securitylogin") //login
.usernameParameter("username") //optional
.passwordParameter("password") //optional
.defaultSuccessUrl("/loggedin")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.permitAll();`
Authentication part is working as expected but not the Google login part. After the Google login i am getting the email and fetching his details from the server and redirecting to one controller but the controller his reloading n number of times. I dont know why the single method is getting reloaded again and again.
http.antMatcher("/loginwithgoogle/**").anonymous();
If i use the above line the Google login part is working fantastically but the normal login authentication is not getting access.
web.ignoring().antMatchers(HttpMethod.POST, "/loginwithgoogle");
I tried the above one too but the same controller is reloading again and again for n number of times. Please help me to move on further. Anything else am i missing or am i going in the wrong way??
Actually i tried the same thing before but no idea why i didnt getting succeeded but the following thing works for me and updated the same if it helps for anyone.
http
.authorizeRequests()
.antMatchers("/loginwithgoogle/**").anonymous() //works this order
.anyRequest().authenticated() // with this line too
.antMatchers("/","/securitylogin").permitAll()
i dont know whether there is seperate order will be there or not but i tried the anonymous() seperately but didnt worked. The above is working perfectly.
UPDATE 11.09.2018
The Google login is working perfectly but roles are not working (ie) User can able to access the admin pages and exception handling is not working correctly.

Spring SSO and account creation

So I'm working on a university project in which my group needs to create an android application that talks to a backend build with spring. So far we've been using JWT's for user authentication/authorization and everything was fine and dandy. However, our client wants to have single sign-on with Google and Facebook and of course to still be able to create an account, just like this form (but on android, not a browser).
I have spent the last month researching and googling how to do this and especially how it's supposed to integrate with the android app. I feel like I'm missing a key point because I see this everywhere, so I assume that is not that hard to do. As much as I understand, I can have two endpoints: login/google, login/facebook to get authorised with their authorisation server. That I have, I followed this guide and I understand 70-ish% of it.
Then my idea is to have users that are logging in for the first time to be saved in our database. I'm not entirely sure how to do that (because I'm not entire sure how the SSO spring code works..). My main questions tho are:
How to have both social login with google/fb and the ability to make an account/login with credentials.
If the user was to make an account, do I have my own authorisation server where I store credentials or do I manage that on the main server.
How do I handle that from the android app? Do I store the refresh token or do I do something else?
There are a couple of things
You want to integrate with spring-social for any social providers such as google/fb. Add the dependency and configure by following the tutorials
See https://github.com/spring-projects/spring-social/wiki/quick-start
If you also want users to create their own account, u do not need an authorization server. What u need is spring security vanilla form setup with a configuration
Something like
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login/")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("j_username")
.passwordParameter("j_password")
.successHandler(authenticationSuccessHandler())
.failureHandler(authenticationFailureHandler())
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(logoutSuccessHandler())
.invalidateHttpSession(true)
}
Yes but i recommend u find an oauth library you can just plug in.. and hopefully it will handle the refresh_token logic for you.. you should not need to implement these things yourself.
I hope this helped some, these questions you asked are very broad.. but hopefully it will get you somewhere.

Resources