Spring security user manual login session creation without password by admin - spring

I am building a web application with spring, hibernated for backend and I am using html,css, javascript jquery forfrontend . I have created signup page, login page and home page. The flow is, User creates account and logins with username and password and if he is authenticated then he is redirected to home page. We do not store password in plaintext form for security reasons. Now I am the administrator and creator of the web application and sometimes a need arises for admin to change data for user or demonstrate what user can do in the interface. What I need to do is create a login session of the user and make changes in his account and/or demonstrate how user can do things on the website(by sharing screen). I want to create a user's session manually, as password is stored in plaintext form I can not login with username and password. Is there a way I can create browser login session without password. I am sharing screenshots of my web applications login page and home page. I am also sharing spring security configuration class. Is there a way I can just specify a username and spring can create a login session for me and I can access user's account just like a normal user session.
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// add a reference to our security data source
#Autowired
private DataSource myDataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(myDataSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/signup_page","/forgot_password","/signup","/reset_password").permitAll()
.antMatchers("/resources/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login_page")
.loginProcessingUrl("/authenticateTheUser").permitAll()
.defaultSuccessUrl("/home_page")
.and()
.logout()
.logoutSuccessUrl("/login_page?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.sessionManagement()
.sessionFixation()
.migrateSession()
.invalidSessionUrl("/login_page")
.maximumSessions(3)
.expiredUrl("/login_page?logout");
}
}
below are the images of my web application.

Two concepts that you may want to look into are:
Pre-Authentication, normally for cases where you are behind a gateway that performs authentication prior to your application (see RequestHeaderAuthenticationFilter)
Switch User for cases where an ADMIN needs to impersonate a USER (see SwitchUserFilter)
Both of these require careful consideration and proper use so as not to accidentally open you up to bypassing authentication entirely. If you're just doing this in a development environment, enabling pre-authentication by adding a RequestHeaderAuthenticationFilter could work for you.

Related

Spring Security: how to recognize, in a public page, that a user is authenticated

I have a simple Spring Boot web application consisting of 2 pages:
a Home Page (freely accessible) at the url https://example.com/
a secured page (requires login for being accessed) at the url https://example.com/secure/page.html
In the Home Page I'm printing the First Name of the visiting user (if he/she is already authenticated) or a sentence saying that the page is visited by an anonymous user.
I'm using Keycloak as far as authentication is concerned.
Here the Spring Security configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/secure/**")
.authenticated()
.and()
.csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
.and()
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
}
If the user is already authenticated, the problem is that the Home Page says he is anonymous because the Principal is always null.
But if the user enters the secured page (and Keycloak lets him in because he's already authenticated) when he comes back to the Home, the page contains - correctly - his First Name.
Where is my configuration wrong?
It seems that Spring Security doesn't check the authentication on non secured pages. Is there a way to tell Spring Security to check every page (both secured and non-secured)?
Thanks in advance for your support.
The solution to this problem is to add /** to security context/handling (with permitAll()).
The art is to do it correctly:
Multiple antMatchers in Spring security (First ant matcher wins!!, https://www.google.com/search?q=spring+security+permitall+not+working)
http://blog.florian-hopf.de/2017/08/spring-security.html
So in this case:
http
.authorizeRequests()
.antMatchers("/secure/**").authenticated()
.antMatchers("/**").pernmitAll()
.and()...
...should fill the (anonymous) Principal also in "permitted area" (i.e. /**(!) ...and leave secure/** restricted!;).
To the core/title question (once Principal is filled), i think the answer is already given:
here (verbally): https://stackoverflow.com/a/26117007/592355
and here(with code): https://stackoverflow.com/a/57054816/592355
..if you use Spring Security (JSP) Taglibs isAnonymous() is handy, and otherwise (in default) you just need to check for hasRole('ROLE_ANONYMOUS') (Ref)

Spring Boot OAuth2 Single Sign On Concept not working

I am trying to develop OAuth2 Client Application with Single Sign On. I have already developed Authorization Server and tested with Client Credentials flow and its working fine. But when I try to use Authorization Code Grant with Single Sign On I could not get it right. Client application takes me to Login Screen when I access authenticated URL, but once authenticated I am redirected to call back url that's fine. But afterwards I could not access any URL as it all authenticated URL are automatically redirected to CALL BACK url. I have permitted call back url in my Security class
My requirement is once authenticated it will allow other urls normally before authentication it should not allow any url.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeRequests()
.antMatchers("/","/index.html", "/home.html", "/login**","/webjars/**", "/error**","/favicon.ico**","/oauth/token","/oauth/authorize**","/demo/1")
.permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.httpBasic();
Here the call back url is demo/1 and Spring Security is not permitting any other url here.
My requirement is once authenticated it should allow other urls normally before authentication it should not allow any url.
http.authorizeRequests().antMatchers("/","/resources/**", "/**").permitAll().anyRequest().authenticated().and().formLogin()
.loginPage("/").permitAll().usernameParameter("username").passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check").failureUrl("/")
.successHandler(myAuthenticationSuccessHandler()).and().logout().logoutSuccessUrl("/")
.logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("JSESSIONID").and().csrf().disable().headers().frameOptions().sameOrigin();

How to check if user still logged in via azure sso (oAuth2), while using my own webapp?

I'm developing an web application with Spring Boot using Azure AD and OAuth2.0 for authentication to secure up the backend.
If I log-out via for example the Outlook Web App, my web application should register this process and logout as well (at least if I reload or reopen the page). How do i implement that? Now the Web-Application seems as still logged in. Unfortunately I did not find an approach to implement this behavior consistently. Only if I use the self-implemented log-out button, it shows the desired effect and the HttpSession gets invalidated and cookies where deleted.
I have already implemented a login and logout via Azure AD in my web application (see code). As soon as I log-out via the button of my own application, I am automatically logged out of other Azure applications (e.g. Outlook Web App) that require Azure SSO.
I already tried the #PreAuthorize Annotation discribed here Spring MVC - Checking if User is already logged in via Spring Security? but this seems not to be the solution.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
http.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.clearAuthentication(true)
.logoutSuccessUrl("https://login.microsoftonline.com/common/oauth2/logout");
}
Redirect to main page:
#GetMapping("login/oauth2/code/azure")
public ModelAndView redirectToRoot(ModelMap modelMap) {
return new ModelAndView("redirect:/", modelMap);
}
I have never implemented this myself, but if I remember right, all OAuth2 providers have some kind of a SingleSignOut endpoint, if you call this in your logout method, it will log the user out from every app that is connected to this provider.
After refreshing the page of your webapp, the security should recognize that the user is then no longer logged in and redirect him to the login page.
Hope I could help you a bit. :)
Edit: I found this after a quick search: https://github.com/juanzero000/spring-boot-oauth2-sso .

Spring boot and Spring Security, different logon forms to use different success handlers

I have a spring boot/mvc site using spring security.
I have to use ways of logging in,
In the navbar present on each page
and the login page which you are redirected to when attempting to access a restricted resource.
For the navbar i'd like the user to stay on the page after successful login
For the login page i'd like the user to be redirected to the resource they were trying to originally access after login.
I can do each functionality individually
First use case is handled by:
SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
handler.setUseReferer(true);
Second case is the default functionality.
But i've been unable to make them both work.
Does anyone have any insights on how to achieve this?
You can configure each login page with a different AuthenticationSuccessHandler like described here
https://www.baeldung.com/spring_redirect_after_login
Like:
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.successHandler(myAuthenticationSuccessHandler())
.and()
.formLogin()
.loginPage("/login2.html")
.loginProcessingUrl("/login2")
.successHandler(mySecondAuthenticationSuccessHandler())
// ...
}

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