Controller part of Spring Security - spring

I have created a custom authentication service for spring-security by implementing the interface UserDetailsService, which is refereed in a security-context.xml as a bean so it will be loaded when application starts. Currently the situation is, I have a LoginController with mapping to bean, a service which calls a method in DAO for checking if the username and password is correct. I just don't know what should come under controller. I am posting the code below. Kindly let me know what am I missing in controller. Thank you for your time.
LoginController.java :
#Controller
#RequestMapping(value = "/login",method = RequestMethod.GET)
public class LoginController {
#Resource(name="userDetailsService")
private LoginService loginService;
}
LoginService.java
#Transactional
#Service("userDetailsService")
#RequestMapping("")
public class LoginService implements UserDetailsService{
#Autowired private UserDao userDao;
#Autowired private Assembler assembler;
#Override
#Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails userDetails = null;
User user = userDao.findByName(username);
if(user == null) { throw new UsernameNotFoundException("Wrong username or password");}
return assembler.buildUserFromUserEntity(user);
}
}
Security-applicationContext.xml
<import resource="servlet-context.xml" />
<!-- Global Security settings -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- Spring Security framework settings -->
<security:http use-expressions="true" auto-config="false" access-denied-page="/403" disable-url-rewriting="true">
<security:session-management>
<security:concurrency-control max-sessions="3" error-if-maximum-exceeded="true"/>
</security:session-management>
<security:form-login login-page="/users" default-target-url="/users" always-use-default-target="true"
authentication-failure-url="/denied" username-parameter="username" password-parameter="password" />
<security:logout logout-url="/logout" logout-success-url="/login?out=1" delete-cookies="JSESSIONID" invalidate-session="true" />
<security:intercept-url pattern="/*" requires-channel="any" access="permitAll" />
<security:intercept-url requires-channel="any" pattern="/login*" access="permitAll"/>
<security:intercept-url pattern="/**" requires-channel="any" access="hasRole('ROLE_USER')" />
</security:http>
<!-- queries to be run on data -->
<security:authentication-manager alias="authenticationManager" >
<security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>
</beans>
Servlet-context.xml
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<!-- Enables the Spring MVC #Controller programming model -->
<resources mapping="/resources/**" location="/resources/" />
<!-- beans start here -->
<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>
<context:component-scan base-package="com.WirTauschen"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
Login form HTML code
**<form id="form" action="<c:url value='/login'/>" method="POST">
<div class="box-wrapper">
<h4>LOGIN</h4>
<div class="iconic-input">
<input type="text" placeholder="Username" name="j_username" value="">
<i class="icons icon-user-3"></i>
</div>
<div class="iconic-input">
<input type="password" placeholder="Password" name="j_password" value="">
<i class="icons icon-lock"></i>
</div>
<input type="checkbox" id="loginremember"> <label for="loginremember">Remember me</label>
<br>
<br>
<div class="pull-left">
<input name="submit" type="submit" class="orange" value="Login">
</div>
<div class="pull-right">
Forgot your password?
<br>
Forgot your username?
<br>
</div>
<br class="clearfix">
</div>
<div class="footer">
<h4 class="pull-left">NEW CUSTOMER?</h4>
<a class="button pull-right" href="create_an_account.html">Create an account</a>
</div>
</form>
</li>
</ul>
</li>
<li><i class="icons icon-lock"></i> Create an Account</li>
</ul>
</nav>

Related

Spring security remember me cause 404

I am trying to use remember me, that seems to be very simple but I get a 404 when I launch the application (404 not found).
My jsp looks like that :
<form class="login" name='loginForm' action="<c:url value='/j_spring_security_check' />" method='POST'>
<input id="j_username" name="j_username" type="text" placeholder="Username" />
<input id="j_password" name="j_password" type="password" placeholder="Password" />
<input name="submit" type="submit" value="Sign In" class="btn btn-success btn-sm" />
<div class="remember-forgot">
<div class="row">
<div class="col-md-6">
<div class="checkbox">
<label>
<input type="checkbox" name="_spring_security_remember_me" />
Remember Me
</label>
</div>
</div>
<div class="col-md-6 forgot-pass-content">
Forgot Password
</div>
</div>
</div>
</form>
and My spring security xml :
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/j_spring_security_check" access="permitAll" />
<intercept-url pattern="/*" access="hasRole('ROLE_USER')" />
<form-login
login-page="/login"
login-processing-url="/j_spring_security_check"
default-target-url="/admin"
username-parameter="j_username"
password-parameter="j_password"
authentication-failure-url="/login?error" ></form-login>
<logout logout-success-url="/login?logout" />
<csrf disabled="true"/>
<remember-me key="myAppKey" />
</http>
<beans:bean id="CustomAuthenticationProvider" class="com.meltum.springconfiguration.CustomAuthenticationProvider" />
<authentication-manager>
<authentication-provider ref="CustomAuthenticationProvider" />
</authentication-manager>
Does anybody know how to solve it ?
Try to name remember me checkbox same as in the spring security configuration -"remember_me". Or you can use default value "_spring_security_remember_me" with just "key" property in configuration.

Spring Basic authentication

Hi I have some login form configuration for authentication and i want to replace my simple login form by
response.setHeader("WWW-Authenticate", "Basic realm=\"/\"");
response.setStatus(401);
response.setHeader("Location", url);
to behave like this form and used spnegoAuthenticationProcessingFilter:
<div id="login-box">
<h3>Login with Username and Password</h3>
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>
<c:if test="${not empty msg}">
<div class="msg">${msg}</div>
</c:if>
<form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</div>
This is my spring security configuration:
<?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:sec="http://www.springframework.org/schema/security"
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-3.2.xsd">
<sec:http entry-point-ref="spnegoEntryPoint" auto-config="false" >
<sec:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<sec:form-login login-page="/login" default-target-url="/hello" always-use-default-target="true"/>
</sec:http>
<bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
<bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosAuthenticationProvider"/>
</sec:authentication-manager>
<!-- Login form auth -->
<bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<property name="kerberosClient">
<bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<property name="debug" value="true" />
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>
<bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<property name="debug" value="true" />
<property name="krbConfLocation" value="/apps/bin/krb5/krb5.conf" />
</bean>
<bean id="dummyUserDetailsService" class="com.web.ldap.DummyUserDetailsService"/>
</beans>
This is possible ?
I do this by that
<sec:http>
<sec:intercept-url pattern="/**" access="ROLE_USER" />
<sec:http-basic entry-point-ref="spnegoEntryPoint"/>
<!-- <sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" /> -->
</sec:http>
but now i don't have spnegoAuthenticationProcessingFilter working...
If i uncomment custom-filter my application will not work

Spring 3 - In CustomUserDetailsService class, i am getting resource null

Hi i am adding spring security to my application (spring with angular). But i am getting my service resource as null. Following is my code.
here is my security.xml contents
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<http auto-config="true" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/home" access="isAuthenticated()" />
<form-login />
</http>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/" />
</beans:bean>
<beans:bean id="securityFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler"
ref="authenticationSuccessHandler" />
</beans:bean>
<beans:bean id="customUserDetailsService" class="com.dashboard.service.CustomUserDetailsService"/>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService"/>
</authentication-manager>
<beans:bean id="authenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/home" />
</beans:bean>
</beans:beans>
and my custom user details service class is
#Service
public class CustomUserDetailsService implements UserDetailsService {
#Resource
UserRepository userRepository;
#Resource
UserService userService;
#Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
try{
User user = userService.getUser(email);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
and my angular controller is
DashBoard.controller('LoginController', function($scope,$http,$location) {
$scope.login = function(){
var data = "j_username="+$scope.username+"&j_password="+$scope.password+"&_spring_security_remember_me=true";
$http.post('j_spring_security_check', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).success(function(data,status) {
$location.path('/home');
}).
error(function(data,status) {
console.debug("failed :"+status+" Data : "+data);
$location.path('/login');
});
};
});
and login form is
<form class="form-horizontal" name="signUpForm" ng-controller="LoginController" ng-submit="login()">
<input class="span12 tenF" ng-model="username" type="email" id="j_username" name="j_username" placeholder="E-mail address" required>
<input class="span12 tenF" type="password" ng-model="password" id="j_password" name="j_password" placeholder="Password" required>
<input class="span3 btn btn-large btn-block btn-success" type="submit" value="Login" style="float:right;font-size:20px;margin-top:10px;">
</ng-form>
while debugging i reaches to
User user = userService.getUser(email);//.findByEmail(email);
but userService is null. Can any one kindly help me figure out why it is null.
The problem is the mixing of xml configuration and annotation based autowiring.
In such an situation, I usual add an constructor that take all the required parameter and add in the xml autowire="constructor"
public class CustomUserDetailsService implements UserDetailsService {
private UserRepository userRepository;
private UserService userService;
#Autowire
public CustomUserDetailsService(UserRepository userRepository,
UserService userService){
this.userRepository=userRepository;
this.userService=userService;
}
....
}
<beans:bean id="customUserDetailsService"
class="com.dashboard.service.CustomUserDetailsService"
autowire="constructor"/>

springframework 'form' tag + spring security auth

What I want. I want do spring security auth by springframework tag 'form'.
Example
<!-- JSP -->
<form:form action="login" commandName="?" >
<form:errors path="lastError" ></form:errors>
<form:input path="j_username" />
<form:password path="j_password" />
<form:button value="submit" name="submit" />
</form:form>
<!-- security-context.xml -->
<http use-expressions="true">
<intercept-url pattern="/client/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" login-processing-url="/login"
authentication-failure-handler-ref="authHandler" />
<logout logout-url="/logout" logout-success-url="/" />
</http>
What should be instead of "?" in form commandName or how can I do this wily action?
Thanx for any suggestions.
Put a Loginbean in the commandName that contains the j_username and j_password.
How to make extra validation in Spring Security login form?

Spring Security: jdbc-user-query, PreparedStatementCallback

I got a problem with my query but I don't know what has caused it so I need your help =)
I got the following exception:
PreparedStatementCallback; bad SQL grammar [select USERNAME as username, PASSWORD as password, from ams.user where USERNAME=?]; nested exception is com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from ams.user where USERNAME='admin'' at line 1
Here's my login.jsp:
<div class="box">
<h1><spring:message code="login.description" /></h1>
<br/>
<form name='f' action="<c:url value='j_spring_security_check' />" method='POST'>
<ol>
<li>
<label><spring:message code="user.user" />:</label>
<em><img src="images/star_red.png" alt="required"></img></em>
<input type='text' name='j_username'>
</li>
<li>
<label><spring:message code="user.password" />:</label>
<em><img src="images/star_red.png" alt="required"></img></em>
<input type='password' name='j_password' />
</li>
<li>
<label> </label>
<input type='hidden' name='remember_me' id="remember_hidden" value="false"/>
<input type='checkbox' id='remember_checkbox' onchange="toggleRememberMe()" class="checkbox"/>
<spring:message code="login.remember" />
</li>
<li>
<label> </label>
<input type="submit" value="<spring:message code="login"/>"/>
</li>
</ol>
<br />
<br />
</form>
<c:if test="${not empty param.login_error}">
<div class="error">
<br />
<spring:message code="login.error" />
<br />
<spring:message code="login.errorReason" />:
<c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</div>
</c:if>
</div>
Here's my Security-Context code:
<?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:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx"
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-3.1.xsd">
<!-- <security:http auto-config="true" access-decision-manager-ref="accessDecisionManager"> -->
<security:http auto-config="true">
<security:intercept-url pattern="/login/login.do" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/login/doLogin.do" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/lib/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_REMEMBERED" />
<security:form-login login-page="/login/login.do" authentication-failure-url="/login/login.do?login_error=true" default-target-url="/test/showTest.do"/>
<security:logout logout-success-url="/login/login.do" invalidate-session="true" />
<security:remember-me key="rememberMe"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select USERNAME as username, PASSWORD as password, from ams.user where USERNAME=?"
authorities-by-username-query="
select distinct user.USERNAME as username, permission.NAME as authority
from ams.user, ams.user_role, ams.role, ams.role_permission, ams.permission
where user.ID=user_role.USER_ID AND user_role.ROLE_ID=role_permission.ROLE_ID AND role_permission.PERMISSION_ID=permission.ID AND user.EMAIL=?"/>
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256" />
</bean>
</beans>
Does anyone have an idea what might have caused this error?
Would really appreciate your help on this one =)
There is a comma in the sql after password, remove that
change sql from
select USERNAME as username, PASSWORD as password, from ams.user where USERNAME=?
to
select USERNAME as username, PASSWORD as password from ams.user where USERNAME=?

Resources