How to display error message in my JSP page using spring security 2.0 - spring

Hi I am now using spring security. It works fine. But if login failed, no error message display. I am wondering how can I display error message?
I have configured the ResourceBundleMessageSource in my applicationContext.xml
<!-- Spring security error message config -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
And my security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:David="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<David:http auto-config="true" access-denied-page="/accessDenied.html">
<!-- Don`t set any role restriction on login.jsp -->
<David:intercept-url pattern="/login.jsp"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- Restrict access to All other pages -->
<David:intercept-url pattern="/admin.jsp"
access="ROLE_ADMIN" />
<!-- Set the login page and what to do if login fails -->
<David:form-login login-page="/login.jsp"
default-target-url="/"/>
<David:logout logout-success-url="/" />
</David:http>
<!-- Specify login examnination strategy -->
<David:authentication-provider>
<David:password-encoder hash="md5" />
<David:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password, status as enabled from user where username=?"
authorities-by-username-query="select u.username,r.name as authority
from user u
join user_role ur
on u.id=ur.user_id
join role r
on r.id=ur.role_id
where u.username=?" />
</David:authentication-provider>
</beans>
My jsp page:
<%# page contentType="text/html;charset=utf-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# page
import="org.springframework.security.ui.AbstractProcessingFilter"%>
<%# page
import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"%>
<%# page import="org.springframework.security.AuthenticationException"%>
<form id="myform" class="cmxform" method="post"
action="${pageContext.request.contextPath}/j_spring_security_check">
<fieldset>
<legend>
Please input correct username and password to login
</legend>
<p>
<label for="user">
Username:
</label>
<input id="user" name="j_username" />
</p>
<p>
<label for="pass">
Password:
</label>
<input type="password" name="j_password" id="password" />
</p>
<p>
<input type="submit" class="submit" value="Login" />
</p>
</fieldset>
</form>
Any suggestions? Any help will be appreciated.

<c:if test="${not empty param.login_error}">
<div class="error">
Your login attempt was not successful, try again.<br />
Reason: #{sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>

This works
<c:if test="${param.error != null}">
Error
</c:if>

Where is the jsp to actually display the error? Something like
<c:if test="${not empty param.error}">
<!-- Display error message -->
</c:if>
If you want to customize this message, you should also look at this

Maybe you can try this...put
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
for c tag on jsp page, and then put something like below for error msg display
<c:when test="${param.error == 1}">
<h3 style="font-size:20; color:#FF1C19;">Wrong id or password!</h3>
</c:when>
"param.error == 1" can get return value from Spring Security(security-config.xml) like
<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key="org.springframework.security.core.userdetails.UsernameNotFoundException">/login.action?error=1</beans:prop>
</beans:props>
</beans:property>
</beans:bean>

This worked for me :
<c:if test="${not empty sessionScope.SPRING_SECURITY_LAST_EXCEPTION}">
<div class="error">
Your login attempt was not successful, try again.<br />
Reason: ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>

I am using spring-security v 4.0.3.RELEASE
Using the not empty did not work for me. However checking for null worked for me.
<c:if test="${ param.error ne null}">
Display error message
</c:if>

Related

spring authentication: can't logout

I'm new to Spring. I can't logout with spring security.
Login works fine, and I'm following this post to implement the logout function.
but I can't make it work.
here's my spring-security.xml:
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/index" access="hasRole('ROLE_USER')" />
<security:logout logout-success-url="/index" logout-url="/logout" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="matt3o" password="secret" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
and here's my index.jsp:
<c:if test="${pageContext.request.userPrincipal.name != null}">
<h2>Welcome : ${pageContext.request.userPrincipal.name}
</c:if>
<p>Logout</p>
Please can somebody explain to me how loggin/loggout works and why my logout doesn't ?
In index.jsp I'm trying to logout in different ways, none of them works:
<!--1-->
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
Logout
</c:if>
<br><br>
<!--2-->
logout1
<br><br>
<!--3-->
<a href='<c:url value="j_spring_security_logout" />'>logout</a>
Spring Security 4 requires a POST request to logout instead of a GET. Next to that by default it is secured using a CSFR token, which you would need to add to the form (see the javadoc).
So instead of a link use a form to invoke the logout.
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Log out" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
or when using the security tag library
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Log out" />
<sec:csrfInput />
</form>
See also here and here in the reference guide.
If you want to use a GET either configure the logout functionality as such that it supports GET requests (for this you need to provide an ant matcher) or by disabling CSFR which can be done by adding <sec:csfr disabled="true" /> to your xml configuration.
you can use
href="<c:url value="/logout"/>"

How To Configure /oauth/token ModelAndView in Spring

I successfully configured an oauth spring application. However, my headache is how to make it return to the login page with a successful token; The log shows the following entry:
`DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling`
Here is my login page:
` <c:url value="/oauth/token" var="loginProcessingUrl"/>
<form:form action="${loginProcessingUrl}" method="post">
<fieldset>
<legend>Please Login</legend>
<!-- use param.error assuming FormLoginConfigurer#failureUrl contains the query parameter error -->
<c:if test="${param.error != null}">
<div>
Failed to login.
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</c:if>
</div>
</c:if>
<!-- the configured LogoutConfigurer#logoutSuccessUrl is /login?logout and contains the query param logout -->
<c:if test="${param.logout != null}">
<div>
You have been logged out.
</div>
</c:if>
<c:if test="${param.success != null}">
<div>
You have been successfully been authenticated.
</div>
</c:if>
<p>
<label for="username">Username</label>
<input type="text" id="username" name="username"/>
</p>
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
</p>
<!-- if using RememberMeConfigurer make sure remember-me matches RememberMeConfigurer#rememberMeParameter -->
<p>
<label for="remember-me">Remember Me?</label>
<input type="checkbox" id="remember-me" name="remember-me"/>
<input type="hidden" id="client_id" name="client_id" value="11111111"/>
<input type="hidden" id="client_secret" name="client_secret" value="2222222"/>
<input type="hidden" id="grant_type" name="grant_type" value="password"/>
<input type="hidden" id="response_type" name="response_type" value="token"/>
<input type="hidden" id="redirect_uri" name="redirect_uri" value="/login?success=1"/>
</p>
<div>
<button type="submit" class="btn">Log in</button>
</div>
</fieldset>
`
And here's my spring-security.xml file:
`<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>`
Why can't I go back to the login page once a token is successfully issued. Any help is appreciated.
Thanks

spring security bad credentials even though they are correct

I am using Spring Roo and I setup my Spring Security like this (applicationContext-security.xml):
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- HTTP security configurations -->
<http auto-config="true" use-expressions="true" request-matcher="regex">
<form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
<logout logout-url="/resources/j_spring_security_logout" />
<intercept-url pattern="\A/hotels\?form.*\Z" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="permitAll"/>
</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">
<!-- <salt-source user-property="login"/> -->
</password-encoder>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
SELECT login, password, enabled
FROM user WHERE login = ?"
authorities-by-username-query="
FROM user u, role r,
user_role ur
WHERE u.id = ur.user
AND r.id = ur.role
AND u.login = ?"
/>
<user-service>
<user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
<user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Then I created a dummy user with the login johnny and the password admin, which is stored in the database like this 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918.
This is the default login page provided by the framework:
<div xmlns:spring="http://www.springframework.org/tags" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<spring:message code="security_login_title" var="title" htmlEscape="false" />
<util:panel id="title" title="${title}">
<c:if test="${not empty param.login_error}">
<div class="errors">
<p>
<spring:message code="security_login_unsuccessful" />
<c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
.
</p>
</div>
<br/>
</c:if>
<c:if test="${empty param.login_error}">
<p>
<!-- <spring:message code="security_login_message" /> -->
</p>
</c:if>
<spring:url value="/resources/j_spring_security_check" var="form_url" />
<form name="f" action="${fn:escapeXml(form_url)}" method="POST">
<input type="hidden" name="test"/>
<div>
<label for="j_username">
<spring:message code="security_login_form_name" />
</label>
<input id="j_username" type='text' name='j_username' style="width:150px" />
<spring:message code="security_login_form_name_message" var="name_msg" htmlEscape="false" />
<script type="text/javascript">
<c:set var="sec_name_msg">
<spring:escapeBody javaScriptEscape="true">${name_msg}</spring:escapeBody>
</c:set>
Spring.addDecoration(new Spring.ElementDecoration({elementId : "j_username", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "${sec_name_msg}", required : true}}));
</script>
</div>
<br />
<div>
<label for="j_password">
<spring:message code="security_login_form_password" />
</label>
<input id="j_password" type='password' name='j_password' style="width:150px" />
<spring:message code="security_login_form_password_message" var="pwd_msg" htmlEscape="false" />
<script type="text/javascript">
<c:set var="sec_pwd_msg">
<spring:escapeBody javaScriptEscape="true">${pwd_msg}</spring:escapeBody>
</c:set>
Spring.addDecoration(new Spring.ElementDecoration({elementId : "j_password", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "${sec_pwd_msg}", required : true}}));
</script>
</div>
<br />
<div class="submit">
<script type="text/javascript">Spring.addDecoration(new Spring.ValidateAllDecoration({elementId:'proceed', event:'onclick'}));</script>
<spring:message code="button_submit" var="submit_label" htmlEscape="false" />
<input id="proceed" type="submit" value="${fn:escapeXml(submit_label)}" />
<spring:message code="button_reset" var="reset_label" htmlEscape="false" />
<input id="reset" type="reset" value="${fn:escapeXml(reset_label)}" />
</div>
</form>
</util:panel>
</div>
However, when I try to log in I get a Bad credentials error. What is happening?
I can't really manage to find a way of how to debug this because it's all happening internally in spring security I guess so I can't get to know what queries are actually being made and I can't/don't know where to look to figure out why this is failing.
Look at the debug log output when you try to authenticate as the user (always a good idea). Most likely it says it can't find the user "johnny".
This is most likely because you have both a jdbc-user-service and a user-service in the same authentication-provider which won't work.
Use two separate authentication-provider elements:
<authentication-provider>
<jdbc-user-service ... />
</authentication-provider>
<authentication-provider>
<user-service>
....
</user-service>
</authentication-provider>
Also, as I said in your other question, you shouldn't use SHA as a password hashing algorithm unless it's for a legacy system.
After more suffering I managed to solve it. I made the user and role entities-tables again and re-wrote the queries:
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT u.login, u.password, u.enabled from users u where u.login=?"
authorities-by-username-query="SELECT u.login, r.name FROM users u left join user_roles ur on u.id=ur.user join roles r on ur.roles=r.id WHERE u.login=?"
/>
Using two separte authentication-provide had nothing to do with my error.

Using Spring Security, how to stay on the login page after a successful login?

Using Spring Security, how can I stay on the login page after a successful login?
This part of my Spring config file:
<http auto-config="true" use-expressions="true">
<form-login authentication-failure-url="/index.jsp?failed=true" default-target-url="/index.jsp" />
<logout logout-success-url="/index.jsp" />
</http>
And I have a jsp fragment file /WEB-INF/jsp/subhead.jspf:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<c:url var="postLoginUrl" value="j_spring_security_check" />
<c:url var="logoutUrl" value="j_spring_security_logout"/>
<c:if test="${param.failed == true}">Login Failed...</c:if>
<security:authorize access="isAnonymous()">
<form action="${postLoginUrl}" method="post">
Username: <input type="text" name="j_username"/>
Password: <input type="password" name="j_password" />
<input type="submit" value="Log in"/>
</form>
</security:authorize>
<security:authorize access="isAuthenticated()">
Hi, <security:authentication property="principal.username"/> Log out
</security:authorize>
I have a page say test.jsp:
<html>
<body>
<%# include file="/WEB-INF/jsp/subhead.jspf" %>
</body>
</html>
How can I make
login success
login failed
logout
all redirect back to the login page (test.jsp)?
For now, they will all redirect to /index.jsp.

Spring security repeated redirects

I am using spring security in my application. I want the user to be logged in first before accessing any pages on the server, hence i am taking the redirect approach. But the redirect seems to be in an infinite loop cause it redirects me to the login page no matter how many times i submit the page. I tried debugging and the request always hits the GET instead of the POST method as i expected. I am using LDAP authentication using the details entered by the user on the form. Here is the code in the security context xml . Can someone point me in the right direction.
<http pattern="/resources/**" security="none" />
<http auto-config="true">
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login" default-target-url="/dashboard"
authentication-failure-url="/loginfailed" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
When i remove the
<form-login login-page="/login" default-target-url="/dashboard"
authentication-failure-url="/loginfailed" />
it defaults to spring login page and it works but i have to use the user credentials from the configuration xml as opposed to LDAP credentials.
Edit**
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<link rel="stylesheet" href="${contextPath}/resources/css/styles.css" type="text/css">
<h2 style="text-align:center">Login to continue to Application</h2>
<div align="center" class="div">
<form:form method="POST" modelAttribute="login" action="authenticate">
<table>
<tr>
<td><form:label path="username" class="label">Username:</form:label></td>
<td><form:input path="username" class="input"/></td>
<td><form:errors path="username" class="error" /></td>
</tr>
<tr>
<td><form:label path="password" class="label">Password:</form:label></td>
<td><form:password path="password" class="input"/></td>
<td><form:errors path="password" class="error"/></td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit"
value="Login" class="button"/></td>
</tr>
</table>
</form:form>
</div>
thanks
Sree
#sri
as mentioned in your code i can see that you have intercepted the URL "/login*"
now any url with login at the end will be intercepted by spring security and after that you have to put the correct credentials....
now After giving credentials your are redirected to page /login
now its clear that again our url is ending with login hence it is intercepted again by spring security ...
thats why the loop continues....
Possible Solution
this may work for you,
just put the following code below <http pattern="/resources/**" security="none" /> tag as shown:
code:
<http pattern="/resources/**" security="none" />
<http pattern="/Login.html" security="none" />
Ok. Finally i got to a working state. Here are the changes i made to the security context xml
<intercept-url pattern="/login/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
the url regex change. And also the action in my login.jsp is now
action="/login/authenticate"
and finally the controller request mapping path is updated.
Hope this helps anyone who has a similar issue. I am yet to discover if this is the right approach to achieve it but works for now.
-Sree

Resources