Issues with Spring Basic Authentication - spring

I am very new to Spring Security. I want to implement the basic authentication on top of current security mechanism. I have created the configuration as below in security-context.xml.
<http auto-config="true" use-expressions="true" pattern="/test/info/**">
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>
<authentication-manager id="basicAuthentication">
<authentication-provider>
<user-service>
<user name="user1" password="user1Pass" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
It works fine if I don't have any other security configuration. But If I add the below configuration the one which I mentioned above will be overridden. It also calls the class com.aws.web.service.AwsUserDetailsService.
<authentication-manager id="authMgr">
<authentication-provider user-service-ref="**userDetailsService**">
</authentication-provider>
</authentication-manager>
Can any one please let me know how can I resolve this issue?

I have fixed this issue by giving authentication-manager-ref.
<http auto-config="true" use-expressions="true" pattern="/test/info/**" authentication-manager-ref="basicAuthentication">
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>
<authentication-manager id="basicAuthentication">
<authentication-provider>
<user-service>
<user name="user1" password="user1Pass" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>

Related

Move spring-security.xml configuration to java based spring boot configuration

I have a existing project which is implemented in spring and now I am moving this project to spring boot. the existing project contain spring-security.xml
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true" pattern="/dashboard*" use-expressions="true" >
<intercept-url pattern="/dashboard*" access="hasRole('ROLE_NORMAL_USER')" />
<form-login login-page="/logout" default-target-url="/dashboard"
authentication-failure-url="/loginerrorpage" />
<session-management>
<concurrency-control max-sessions="12" expired-url="/logout"/>
</session-management>
<custom-filter after="LOGIN_PAGE_FILTER" ref="LoginFilter" />
<logout invalidate-session="true" logout-success-url="/logout" logout-url="/j_spring_security_logout"/>
<csrf disabled="true" />
</http>
<http auto-config="true">
<intercept-url pattern="/entrance" access="hasRole('ROLE_NORMAL_USER')" />
<form-login login-page="/login" default-target-url="/entrance"
authentication-failure-url="/loginerrorpage" />
<session-management>
<concurrency-control max-sessions="12" expired-url="/logout"/>
</session-management>
<logout invalidate-session="true" logout-success-url="/logout" logout-url="/j_spring_security_logout"/>
<csrf disabled="true" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user1" password="password1" authorities="ROLE_NORMAL_USER" />
<user name="user2" password="password2" authorities="ROLE_NORMAL_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="LoginFilter" class="com.codemaster.LoginFilter"/>
</b:beans>
Is anybody knows how to move above configuration to spring boot configuration
Just Add the flowing class to your project.
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ImportResource("classpath:spring-security.xml")
public class SecurityConfig {
}

Spring security custom session timeout url

Currently I'm working on spring security app, where I need user to be redirected to a custom lock page when session is expired which only contains a password field. (username might be placed in a hidden field inside the login form.) I need to pass username extracted from UserDetails instance and redirect to this custom URL once login session timed out.
I tried to use concurrency-control -> expired-url but it did not give me successful result.
I will be very helpful if you could give some guidence to achieve this.
Is this possible to achieve since I will need to have customized behavior on authentication-failure-url too? (when a given password is incorrect).
Update 1:
My current configuration:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<http auto-config="true" create-session="always" use-expressions="true" entry-point-ref="authEntryPoint" >
<form-login
login-page="/login"
default-target-url="/home"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password"
always-use-default-target="true"/>
<logout invalidate-session="true" logout-success-url="/login" delete-cookies="JSESSIONID"/>
<session-management session-fixation-protection="newSession" invalid-session-url="/"
session-authentication-error-url="/login">
<concurrency-control session-registry-alias="sessionRegistry" max-sessions="10"
expired-url="/lock-screen" error-if-maximum-exceeded="true"/>
</session-management>
<intercept-url pattern="/" access="hasRole('ROLE_LOGIN')"/>
<intercept-url pattern="/profile" access="hasRole('ROLE_LOGIN')"/>
<intercept-url pattern="/home" access="hasRole('ROLE_LOGIN')"/>
<access-denied-handler error-page="/403"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="10"/>
</beans:bean>
<beans:bean id="authEntryPoint" class="com.myapp.admin.security.web.authentication.AjaxSupportedLoginUrlAuthenticationEntryPoint"
scope="singleton">
<beans:constructor-arg name="loginFormUrl" value="/login"/>
</beans:bean>
I'm expecting something like this:
user Login screen:
https://i.stack.imgur.com/vTPkF.png
Lock screen after logged in user being inactive for while:
https://i.stack.imgur.com/DY9kG.png

Spring Security logins fail when migrating Spring mvc projects to Spring boot

I migrated a working Spring mvc project to Spring boot. Refer to Section 81.3 of this document and this question. Modules are working properly, but SpringSecurity can not login.
In the open when the home page will jump to the login page, and then log in after the home page and login page repeatedly redirects are 302 HTTP response, and then an error ERR_TOO_MANY_REDIRECTS.
After debugging, when I log on Custom UserDetailsService can correctly find and return UserDetails, custom SimpleUrlAuthenticationSuccessHandler also called onAuthenticationSuccess normally, but in the filter chain in a call FilterSecurityInterceptor this filter, SpringSecurity login status is cleared, I And does not call logout of the HTTP request.
I carefully check that in the set create-session = "stateless" clear the login status is normal, but it seems that my application can not be properly re-authorized. After the request has been SecurityContextHolder.getContext().GetAuthentication().GetPrincipal() has been anonymousUesr (Cookies correctly passed loginKey = b3668242-574a-498e-bd03-243e28dc805c; SESSIONID_HAP = 98963370-8561-40a2-9898-a5e80f7d1186).
This project is more complex, the following is an important part of the configuration and code, and their role is basically the original and the equivalent.
SpringBootConfigure.java SpringBoot enter point.
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
#ImportResource({"classpath:/spring/applicationContext*.xml","classpath:/spring/appServlet/servlet*.xml"})
public class SpringBootConfigure {
...
}
spring security xml config
<http access-decision-manager-ref="accessDecisionManager">
<csrf disabled="true"/>
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/login.html" access="permitAll" />
<intercept-url pattern="/verifiCode" access="permitAll" />
<intercept-url pattern="/common/**" access="permitAll" />
<intercept-url pattern="/boot/**" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<access-denied-handler error-page="/403.html"/>
<form-login login-page='/login' authentication-success-handler-ref="successHandler"
authentication-failure-handler-ref="loginFailureHandler"/>
<custom-filter ref="captchaVerifierFilter" before="FORM_LOGIN_FILTER"/>
<logout logout-url="/logout"/>
<headers defaults-disabled="true">
<cache-control/>
</headers>
</http>
<beans:bean id="loginFailureHandler" class="com.hand.hap.security.LoginFailureHandler"/>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder ref="passwordManager"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="captchaVerifierFilter" class="com.hand.hap.security.CaptchaVerifierFilter">
<beans:property name="captchaField" value="verifiCode"/>
</beans:bean>
<beans:bean id="successHandler" class="com.hand.hap.security.CustomAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/index"/>
</beans:bean>

Spring Security 3.2 Multiple http tag with different Authentication Manager

I am stuck trying to create a web app using spring security 3.2.
I am trying to implement two login pages with a different authentication manager. This configuration works fine if I use a http-basic form but when using a form-login, I receive a 404 on j_spring_security_check. Any Idea ? Why the j_spring_security_check is not generated by spring on this situation ?
Thanks in advance
<http pattern="/admin/login.html" security="none" />
<http pattern="/user/login.html" security="none" />
<http use-expressions="true" pattern="/user/**" authentication-manager-ref="userAuthMgr">
<intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/user/login.html" always-use-default-target="true" default-target-url="/user/index.html" />
</http>
<http use-expressions="true" pattern="/admin/**" authentication-manager-ref="adminAuthMgr">
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<form-login login-page="/admin/login.html" always-use-default-target="true" default-target-url="/admin/index.html" />
</http>
<debug/>
<authentication-manager id="adminAuthMgr">
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
<authentication-manager id="userAuthMgr">
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_USER" />
<user name="vip" password="vip" authorities="ROLE_USER, ROLE_VIP" />
</user-service>
</authentication-provider>
</authentication-manager>
And my login.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<div class="container">
<form class="form-signin" role="form" action="<c:url value='/j_spring_security_check' />" method='POST'>
<input type="text" name='j_username' class="form-control" placeholder="Username" required="" autofocus="">
<input type="password" name='j_password' class="form-control" placeholder="Password" required="">
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
<c:if test="${not empty sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}">
<div class="alert alert-danger">
${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>
You can use multiple authentication provider:
-One 'default' Authentication Provider: with 'alias'
-others Authenfication Provider: with 'id'
<http use-expressions="true" pattern="/user/**" authentication-manager-ref="userAuthMgr">
<intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/user/login.html" always-use-default-target="true" default-target-url="/user/index.html" />
</http>
<http use-expressions="true" pattern="/admin/**" authentication-manager-ref="adminAuthMgr">
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<form-login login-page="/admin/login.html" always-use-default-target="true" default-target-url="/admin/index.html" />
</http>
<debug/>
<!--default Authentication Provider -->
<authentication-manager alias="adminAuthMgr">
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
<authentication-manager id="userAuthMgr">
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_USER" />
<user name="vip" password="vip" authorities="ROLE_USER, ROLE_VIP" />
</user-service>
</authentication-provider>
</authentication-manager>
The way spring works is designed is to use one authentication manager with one or more kinds of authentication providers.
As for your example, why not use one authenticationmanager and authentication provider and reference them in both the http tags.
From a security point of view, it should should not compromise anything.
If it was, then nobody would be using spring security.

Spring security with multiple login pages

I am using Spring security to secure login to the application admin section with a username and password. But now my client need to have another login screen for the application clients section, where they will have their own usernames / passwords to login to the clients section. So far I've already implemented the admin section login successfully with the following spring-security.xml settings:
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login"
default-target-url="/admin/dashboard" always-use-default-target="true"
authentication-failure-url="/login/admin?error_msg=wrong username or password" />
<security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
<security:logout logout-success-url="/login"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider
user-service-ref="adminServiceImpl">
</security:authentication-provider>
</security:authentication-manager>
I've searched the web a lot trying to find how I can add the client section login screen, intercept-url(s), security authentication provider but couldn't find any info, so can someone please help me with any link to any tutorial / example, guide on how to do so?
Thanks
According to the Spring Security docs:
From Spring Security 3.1 it is now possible to use multiple http
elements to define separate security filter chain configurations for
different request patterns. If the pattern attribute is omitted from
an http element, it matches all requests.
Each element creates a filter chain within the internal FilterChainProxy and the URL pattern that should be mapped to it. The elements will be added in the order they are declared, so the most specific patterns must again be declared first.
So, essentially you need two <http> elements each with a different pattern attribute.
There's a detailed tutorial here: https://blog.codecentric.de/en/2012/07/spring-security-two-security-realms-in-one-application/
I would use only one security:http, but register two UsernamePasswordLoginFilters.
This solution would be appropriate if the two Login-Pages belog to the same security-realm. (So if it does not matter on which Login-Page the user logs in). Of course you can still use roles to restrict the access for different parts of your application for different types of users.
This solution should be quite easy, because you will not need to handle two security:http sections.
The major drawback of this is: that you will have to decide on which of the two login pages a NOT logged in user gets redirected if he try to access an page that requires a login.
Example project of Spring MVC App with multiple login forms.
Three types of pages Normal/Member/Admin.
If you try to access member page you are brought to Member Login form.
If you try to access admin page you go to the Admin Login form.
https://github.com/eric-mckinley/springmultihttploginforms
Done using the ant regex request matcher in the seucrity xml config file.
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<global-method-security secured-annotations="enabled" />
<http name="member" pattern="/member/*" request-matcher="ant" auto-config="true" use-expressions="false">
<csrf disabled="true"/>
<intercept-url pattern="/member/home" access="ROLE_MEMBER" />
<intercept-url pattern="/member/account" access="ROLE_MEMBER" />
<intercept-url pattern="/member/orders" access="ROLE_MEMBER" />
<form-login login-page="/member-login" always-use-default-target="false"/>
<logout logout-url="/logout" logout-success-url="/home"/>
</http>
<http name="admin" request-matcher="regex" auto-config="true" use-expressions="false">
<csrf disabled="true"/>
<intercept-url pattern="/admin/home" access="ROLE_ADMIN" />
<intercept-url pattern="/admin/users" access="ROLE_ADMIN" />
<form-login login-page="/admin-login" always-use-default-target="false"/>
<logout logout-url="/logout" logout-success-url="/home"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="password" authorities="ROLE_ADMIN" />
<user name="member" password="password" authorities="ROLE_MEMBER" />
<user name="super" password="password" authorities="ROLE_ADMIN,ROLE_MEMBER" />
</user-service>
</authentication-provider>
</authentication-manager>
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url
pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
<intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
<intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/login-success"
authentication-failure-url="/loginError" />
<!-- <session-management invalid-session-url="/login" session-fixation-protection="newSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management> -->
<logout logout-success-url="/login" delete-cookies="JSESSIONID" />
<csrf disabled="true" />
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
</http>
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/mobile/" access="permitAll" />
<intercept-url pattern="/mobile/login" access="permitAll" />
<!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url
pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
<intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
<intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />
<form-login login-page="/mobile/login" default-target-url="/mobile/login-success"
always-use-default-target="true" authentication-failure-url="/mobile/login?error"
username-parameter="username" password-parameter="password" />
<logout delete-cookies="JSESSIONID" logout-success-url="/mobile/login" />
<csrf disabled="true" />
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
Here I have need two login forms common for all users. I have configured tag element as mentioned above in spring-security.xml.But it is not working. Please suggest me a solution

Resources