Spring MVC: twice auth request - login form and browser window. WHY? - spring

The problem is that after successful authorization on the login form (login.jsp), when trying to access the controllers (path: rest/profile), a browser window appears asking for the username and password (httpbasic).
QUESTION: why Spring Security requires double authentication - entering a password at the login form is not enough?
login.jsp:
<%# page contentType="text/html" pageEncoding="UTF-8" %>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<html>
<jsp:include page="fragments/headTag.jsp"/>
<body>
<jsp:include page="fragments/bodyHeader.jsp"/>
<div class="container">
<div class="d-flex justify-content-center h-100">
<div class="card">
<div class="card-header">
<h3><spring:message code="app.signIn"/></h3>
</div>
<div class="card-body">
<form:form id="login_form" action="spring_security_check" method="post">
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="username" class="form-control" placeholder="<spring:message code="user.login"/>">
</div>
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="password" class="form-control" placeholder="<spring:message code="user.password"/>">
</div>
<div class="row align-items-center remember">
<input type="checkbox"><spring:message code="app.rememberMe"/>
</div>
<div class="form-group">
<button type="submit" class="btn float-right yellow_btn"><spring:message code="app.login"/></button>
</div>
</form:form>
</div>
<br>
<div class="card-footer">
<div class="d-flex justify-content-center links">
<spring:message code="app.notProfileQuestion"/>
</div>
<div class="d-flex form-group justify-content-center">
<a class="btn yellow_btn" href="profile/register"><spring:message code="app.register"/> »</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
spring-security.xml
<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.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/resources/**" security="none"/>
<http pattern="/webjars/**" security="none"/>
<http pattern="/rest/**" use-expressions="true" name="restSecurityFilterChain" create-session="stateless">
<http-basic/>
<intercept-url pattern="/rest/profile/register" access="isAnonymous()"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<csrf disabled="true"/>
</http>
<beans:bean class="org.springframework.security.crypto.factory.PasswordEncoderFactories" id="passwordEncoder" factory-method="createDelegatingPasswordEncoder"/>
<http>
<intercept-url pattern="/login" access="permitAll()"/>
<intercept-url pattern="/profile/register" access="isAnonymous()"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login login-page="/login" default-target-url="/profile"
authentication-failure-url="/login?error=true"
login-processing-url="/spring_security_check"/>
<logout logout-success-url="/login"/>
<!--<csrf disabled="true"/>-->
</http>
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
How to fix problem? I want enter password only once - at login page.

Related

Always authentication failure in Spring security 4.2

I am trying to implement one simple user authentication by Spring Security in Spring MVC model but I am constantly getting "Bad credentials" even if I am providing correct credentials .
Below are my files. Can someone please suggest what am I missing?
Security.xml:
<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
https://www.springframework.org/security/spring-security-4.2.xsd">
<http>
<csrf disabled="true"/>
<intercept-url pattern="/login*" access="ROLE_USER"/>
<form-login login-page="/" default-target-url="/login" authentication-failure-url="/"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="rishavraj#gmail.com" password="123456" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Controller.java:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView Login(#RequestParam Map<String, String> reqvar) {
System.out.println("login");
ModelAndView form = new ModelAndView("Index");
return form;
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView Index() {
System.out.println("Index");
ModelAndView form = new ModelAndView("Index");
return form;
}
Index.jsp:
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION !=null}">
<div class="alert alert-danger fade in">
×
<strong> Wrong Email or Password </strong>
<h4> Caused by :
${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
</h4>
</div>
</c:if>
<form action="/Mail/login" method="post">
<div class="form-group">
<label for="inputUserName">Email</label>
<input class="form-control" placeholder="Email ID" type="text" id="inputUserName" name="Email"/>
</div>
<div class="form-group">
<label for="inputPassword">Password</label>
<input class="form-control" placeholder="Login Password" type="password" id="inputPassword" name="password"/>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Login</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>`
</div>
</form>

<mvc:resources mapping="/resources/**" location="/resources/" />

This is the dispatcher-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.web.controllers" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- <mvc:default-servlet-handler /> -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<title>mypage</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="${pageContext.request.contextPath}/WebContent/resources/mycustom/fabrication.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/WebContent/resources/mycustom/boxmodel.css" rel="stylesheet">
<link href="<c:url value="/resources/css/bootstrap.min.css" />" rel="stylesheet">
<link href="${pageContext.request.contextPath}/WebContent/resources/css/moslake_style.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/WebContent/resources/css/boxmodel.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/WebContent/resources/css/font.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/WebContent/resources/css/media.css" rel="stylesheet">
<script src="<c:url value="/resources/js/jquery.min.js" />"></script>
<script src="<c:url value="/resources/js/bootstrap.min.js" />"></script>
</head>
<body bgcolor="#F5FAFA">
<h1>${pageContext.request.contextPath}</h1>
<div class="header">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="row">
<div class="col-md-5"></div><!--end of first row columns-->
<div class="col-md-2">
<a class="navbar-brand" href="#"><img src="img/swing.png" alt="swing logo" height="50" width="100"></a>
</div>
<div class="col-md-5"></div>
</div><!--end of row-->
<div class="row">
<div class="col-md-5">
<ul class="nav nav-pills">
<li>
<button class="dropdown-toggle btn-primary btn-sm" data-toggle="dropdown" type="button">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<ul class="dropdown-menu">
<li><p align="center">Projects List</p></li>
<li class="divider"></li>
<li><b>Project1</b></li>
<li><b>Project2</b></li>
<li><b>Project3</b></li>
<li><b>Project4</b></li>
<li><b>Project5</b></li>
</ul>
</li>
<li class="dropdown">
<button type="button" class="dropdown-toggle btn-primary btn-sm" data-toggle="dropdown">
<span class="glyphicon glyphicon-plus"></span>
</button>
<ul class="dropdown-menu">
<li><p align="center">Add</p></li>
<li class="divider"></li>
<li><b>New Project</b></li>
</ul>
</li>
<li>
<form class="navbar-search" id="srch" action="#">
<input type="text" class="form-control" placeholder="Search">
</li>
<li>
<button class="btn btn-primary btn-md" type="submit"><span class="glyphicon glyphicon-search"></span>Search</button>
</form>
</li>
</ul>
</div><!--end of col-md-5-->
<div class="col-md-4"></div><!--end of col-md-4-->
<div class="col-md-3">
<ul class="nav nav-pills">
<li>
<a class="btn btn-basic">hello!
<span class="badge">Abbas Kapasi</span>
</a>
</li>
<li class="dropdown">
<button class="dropdown-toggle btn-primary btn-sm" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> <i class="glyphicon glyphicon-chevron-down"></i></button>
<ul class="dropdown-menu">
<li>Profile</li>
<li class="divider"></li>
<li>Logout</li>
</ul>
</li>
</ul>
</div><!--end of col-md-3-->
</div><!--end of nested row-->
</div><!--end of main container-->
</div><!--end of nav-->
</div><!--end of header-->
</body>
</html>
This causes following error:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [resources]
Offending resource: ServletContext resource [/WEB-INF/containers/dispatcher-servlet.xml]

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.

Resources