How to show hide elements using spring security - spring

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>

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"/>

2 authentication managers one authentication object

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">

My csrf token is not getting created

I have the following spring configuration
<http pattern="/signin" security="none" />
<http auto-config="false" use-expressions="true" create-session="ifRequired" entry-point-ref="loginUrlAuthenticationEntryPoint">
<csrf />
.....
</http>
<beans:bean name="requestDataValueProcessor" class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"/>
In my sigin page i have the following as described in spring CSRF documentation
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
But i see both values are empty. I have no clue why it is empty or did i missed any configuration?
You can't have security "none" on the signin page.
Remove the line:
<http pattern="/signin" security="none" />
Instead insert inside your other http:
<intercept-url pattern="/signin" access="permitAll" />

Multiple redirect in the login (Spring MVC)

I am trying to achieve:
After session timeout the user is redirected to the login page and when he login again he should be redirected to the original url that the user entered.
The problem is:
Multiple redirects are happening in the login page. So, if I type http://localhost:8080/app-web/login in the browser then Fiddler shows me the following:
200 /app-web/login
302 /app-web/0
302 /app-web/0/
200 /app-web/login
As a result, after login it is redirecting me to /app-web/0/
I am using apache tiles. Any help will be appreciated and let me know if you need more info about the configuration.
EDIT
Here are few config:
<http auto-config="true"
use-expressions="true"
disable-url-rewriting="true"
entry-point-ref="ajaxAwareAuthenticationEntryPoint">
<form-login login-processing-url="/resources/j_spring_security_check"
authentication-success-handler-ref="postSuccessAuthHandler"
authentication-failure-handler-ref="postFailureAuthHandler"
login-page="/login"
authentication-failure-url="/login?login_error=t"
default-target-url="/pin"/>
<logout logout-url="/resources/j_spring_security_logout" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/auth/resetForgotPassword" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
</http>
The login view:
<mvc:view-controller path="/login"/>
Tiles:
<definition name="login" extends="NoNav.Template" >
<put-attribute name="NoNavMainBodyContainer" value="LoginMainBodyContainer.Template" cascade="true" />
</definition>

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