2 authentication managers one authentication object - spring

I'm trying to protect a resource by defining 2 HTTP elements and 2 authentication managers. Each HTTP element has a separate form to authenticate with. The first form and HTTP element is needed to access any resource. The second form is the authenticate with more complex authentication parameters (username, password, etc)
PROBLEM: When I have authenticated with first form to access the application, this works fine as expected, but then when I try to reach the second protected resource I never get to the form as it see's I need a new role (checks the auth object and fails as the role does not exist) here's where I'm a little lost.
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- Exclude public pages and static resources -->
<http pattern="/favicon.ico" security="none" />
<http pattern="/js/**" security="none" />
<http pattern="/css/**" security="none" />
<http pattern="/img/**" security="none" />
<http pattern="/test**" auto-config="true" use-expressions="true" authentication-manager-ref="smsAuthManager">
<intercept-url pattern="/test" access="hasRole('ROLE_SMS_USER')" />
<intercept-url pattern="/refreshLoginPageTuring" access="permitAll" />
<intercept-url pattern="/loginTuring" access="hasRole('USER')" />
<form-login login-page="/loginTuring"
login-processing-url="/test-login"
authentication-failure-url="/accessdenied"/>
<logout logout-url="/logout" invalidate-session="true"/>
<!-- <access-denied-handler ref="/loginTuring"/> -->
</http>
<http auto-config="true" use-expressions="true" authentication-manager-ref="userPortal">
<intercept-url pattern="/getQRCode" access="permitAll" />
<intercept-url pattern="/refreshLoginPageTuring" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/accessdenied" access="permitAll" />
<intercept-url pattern="/" access="hasRole('USER')" />
<form-login login-page="/login" default-target-url="/menu"
authentication-failure-url="/accessdenied" />
<logout logout-success-url="/logout" />
<intercept-url pattern="/errors/error" access="hasRole('USER')" />
<intercept-url pattern="/menu" access="hasRole('USER')" />
</http>
<authentication-manager id="userPortal">
<authentication-provider ref="userPortalAuthenticationProvider" />
</authentication-manager>
<authentication-manager id="smsAuthManager">
<authentication-provider ref="smsAuthenticationProvider" />
</authentication-manager>
FORM:
<form id="form1" action="/test-login" method="post">
<label for="j_username"><spring:message code = "login.username" /></label>
<input id="j_username" value="${username}" name="j_username" type="text">
<label for="j_password"><spring:message code = "login.password" /></label>
<input id="j_password" value="${password}" name="j_password" type="password">
<label for="otc"><spring:message code = "login.otc" /></label>
<input id="otc" name="otc" type="password">
<button name="submit" type="submit" id="login" onclick="return validateForm()" class="btn btn-primary">Login</button>
<button name="sessionstart" type="submit" id="sessionstart" onclick="return validateAndChangeToRefreshImgAction()" class="btn">Refresh Image</button>
<br/>
<input type="hidden" name="rmShown" value="1">
<img id="scimage" style="block" src="<c:url value="/img/empty.gif" />"/>
</form>
" method="post" class="login-form">
" name="j_username" type="text">

Related

Can't get Spring security "remember me" feature to work

I'm new to Spring and Java. Trying to set up security remember me feature.
Here is my security.xml and login.jsp files. What am I doing wrong?
security.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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-4.0.xsd">
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource"/>
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<security:http use-expressions="true">
<security:intercept-url pattern="/" access="permitAll"/>
<security:intercept-url pattern="/createplayer" access="isAuthenticated()"/>
<security:intercept-url pattern="/players" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/createaccount" access="permitAll"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/logout" access="permitAll"/>
<security:intercept-url pattern="/welcome" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="denyAll"/>
<security:form-login login-page="/login" authentication-failure-url="/login?error=true"/>
<security:remember-me key="MyAppKey" remember-me-parameter="remember-me"
remember-me-cookie="remember-me"
token-validity-seconds="604800"
data-source-ref="dataSource"/>
</security:http>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</bean>
</beans>
login.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h1>Login</h1>
<c:if test="${param.error != null}">
Login failed. Check if username or password are correct!
</c:if>
<form action = "/login", method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
Name <br>
<input name="username"/> <br>
Password<br>
<input type="password" name="password"/> <br>
Remember me <br>
<input type="checkbox" name="remember-me">
<br><br>
<input type="submit"> <br><br>
</form>
<h2>${msg}</h2>
<br>
Create account <br>
</body>
</html>
P.S. I tried adding
<session-config>
<session-timeout>1</session-timeout>
</session-config>
to web.xml to check if "remember me" works, but instead it "remembering me" it always logs out in one minute.
Add id to your jdbc-user-service
<security:jdbc-user-service data-source-ref="dataSource" id="jdbcUserService/>
and refer to your service from remember-me by it's id like this:
<security:remember-me key="MyAppKey"
user-service-ref="jdbcUserService"/>

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.

How to show hide elements using spring security

I have a button which i want to show in login page.
So when the user is logged in i want to hide this button. I think
<sec:authorize access="isAuthenticated()">
is useful for this so i included something like following in my jsp
<sec:authorize access="not isAuthenticated()">
<div class="pull-right">
But is not visible in the login page as well as after logged in.
What can be the problem.
<http pattern="/foobar/static-wro4j/**" security="none"/>
<http pattern="/foobar/static/**" security="none"/>
<http pattern="/foobar/login*" security="none"/>
<http pattern="/foobar/syndic/**" security="none"/>
<http pattern="/foobar/register/**" security="none"/>
<http pattern="/foobar/lostpassword/**" security="none"/>
<http auto-config="true" use-expressions="true" create-session="ifRequired">
<remember-me key="foobarRememberKey" token-validity-seconds="2592000"/>
<intercept-url pattern="/foobar/presentation" access="permitAll()"/>
<intercept-url pattern="/foobar/tos" access="permitAll()"/>
<intercept-url pattern="/foobar/license" access="permitAll()"/>
<intercept-url pattern="/foobar/404-error" access="permitAll()"/>
<intercept-url pattern="/foobar/500-error" access="permitAll()"/>
<intercept-url pattern="/foobar/rest/users" method="POST" access="permitAll()"/>
<intercept-url pattern="/metrics/**" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login
login-processing-url="/foobar/authentication"
login-page="/foobar/login"
authentication-failure-url="/foobar/login?action=loginFailure"
default-target-url="/foobar/"
authentication-success-handler-ref="foobarAuthenticationSuccessHandler"/>
<http-basic/>
<logout logout-url="/foobar/logout"
logout-success-url="/foobar/login"/>
<openid-login authentication-failure-url="/foobar/login?action=loginFailure"
user-service-ref="openIdAutoRegisteringUserDetailsService">
<!-- Only Google Apps is supported -->
<attribute-exchange identifier-match="https://www.google.com/.*">
<openid-attribute name="email" type="http://axschema.org/contact/email" required="true" count="1"/>
<openid-attribute name="firstname" type="http://axschema.org/namePerson/first" required="true"/>
<openid-attribute name="lastname" type="http://axschema.org/namePerson/last" required="true"/>
</attribute-exchange>
</openid-login>
</http>
Make sure you have included the Spring Security Tag Library in the JSP:
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
In your security configuration include:
<beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
Then use the authorize tag:
<sec:authorize access="isAuthenticated()">
<!-- Content for Authenticated users -->
</sec:authorize>
<sec:authorize access="isAnonymous()">
<!-- Content for Unauthenticated users -->
</sec:authorize>

Difficulties with basic Spring Security Configuration

I'm trying to build a very basic, straight-forward authentication for a spring project.
The problem I'm having is that the application constantly sends me to the "login-failed" page, although I've declared 2 basic accounts (admin and user).
my application-Security.xml:
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login/denied" />
<logout logout-url="/resources/j_spring_security_logout" />
<!-- Configure these elements to secure URIs in your application -->
<intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/member/**" access="isAuthenticated()" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/home/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/*Details/*" access="hasRole('ROLE_USER')" />
</http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
<authentication-provider>
<password-encoder hash="sha-256" />
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
<user name="user" password="user" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
my VERY basic login-form:
<form action="/${app_name}/resources/j_spring_security_check" method="POST">
<label for="j_username">Username</label>
<input id="j_username" name="j_username" type="text" /><br/>
<label for="j_password">Password</label>
<input id="j_password" name="j_password" type="password" /><br/>
<input type="submit" value="Login" />
</form>
For now the controller is there only to resolve the URLs for login, login/denied etc.
I'm just starting out with Spring and Roo, so this might just be something obvious that I'm overlooking.
Thanks to anyone taking the time to answer.
Your problem is that you have defined a password-encoder
<password-encoder hash="sha-256" />
while your password is plain text
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
Either remove the encoder or (better) specify the password, encoded with the algorithm you have chosen (sha-256)

Why am I not getting Spring Security Login Error Messages?

Using Spring Security 3 along with Struts 2 and Tiles 2, I have a login page that appears when it is supposed to and performs the login as expected -- however when I enter bad user credentials I am returned to the login page with no information about what went wrong. I've checked all my configuration parameters and I can't see where the problem is.
My Spring Security XML config is as follows:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/public/**" access="permitAll" />
<intercept-url pattern="/home/**" access="permitAll" />
<intercept-url pattern="/user/**" access="hasRole('AUTH_MANAGE_USERS')" />
<intercept-url pattern="/group/**" access="hasRole('AUTH_MANAGE_USERS')" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<access-denied-handler error-page="/403.html"/>
<form-login login-page="/public/login.do" always-use-default-target="false"/>
<logout invalidate-session="true" logout-success-url="/public/home.do"/>
</http>
My Struts Action looks like this:
<package name="public" namespace="/public" extends="secure">
<action name="login">
<result name="success" type="tiles">tiles.login.panel</result>
<result name="input" type="tiles">tiles.login.panel</result>
<result name="error">/WEB-INF/jsp/error.jsp</result>
</action>
<action name="logout">
<result name="success" type="redirect">/j_spring_security_logout</result>
</action>
</package>
And the login.jsp page (part of the tile) looks for the exception from Spring Security...
<c:if test="${not empty param.login_error}">
<span class="actionError">
Your login attempt was not successful, try again.<br/><br/>
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
</span>
</c:if>
<form id="loginForm" name="loginForm" action="/j_spring_security_check" method="post">
...
</form>
Can anyone tell me what I am missing? Thanks in advance for any/all replies.
Spring Security doesn't set param.login_error automatically. You need to do it manaully as follows:
<form-login
login-page="/public/login.do"
authentication-failure-url = "/public/login.do?login_error=1"
always-use-default-target="false"/>
One suggestion for helping with the conversion of error messages like in the final comment is to use an AuthenticationFailureHandler to map different exception types to different error codes that the ui-layer code can lookup unique messages for. It looks like:
<security:form-login login-page="/login"
authentication-failure-handler-ref="authenticationFailureHandler"/>
<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login?reason=login_error"/>
<property name="exceptionMappings">
<map>
<entry><key><value>org.springframework.security.authentication.LockedException</value></key>
<value>/login?reason=user_locked</value></entry>
<entry><key><value>org.springframework.security.authentication.DisabledException</value></key>
<value>/login?reason=user_disabled</value></entry>
<entry><key><value>org.springframework.security.authentication.AuthenticationServiceException</value></key>
<value>/login?reason=connection</value></entry>
</map>
</property>
</bean>

Resources