Announcement Announcement Module
Collapse
No announcement yet.
Custom Login Form Validation Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • antispam
    started a topic Custom Login Form Validation

    Custom Login Form Validation

    Hello guys.

    Not long ago I have started learning Spring (especially @MVC - for developing web apps). It is great, things are moving quite fast. However, I am encountering some difficulties which I cannot overcome. I am using Spring Security to (of course) secure my first Spring web app. The problem is I cannot build a login form that I can also validate.

    In more depth:
    - I have defined the DelegatingFilterProxy filter in web.xml
    - in the spring-servlet.xml (the config for my app) I have defined an UrlBasedViewResolver which maps /example to /WEB-INF/jsp/example.jsp
    - in the spring-security.xml (the second config file used only for security configs) I have:
    HTML Code:
    	<security:http auto-config="true" access-denied-page="/accessDenied">
    		<security:intercept-url pattern="/home"
    			access="ROLE_ALLACCESS, ROLE_URLACCESS" />
    		<security:form-login login-page="/login"
    			default-target-url="/home" />
    	</security:http>
    
    	<security:authentication-manager>
    		<security:authentication-provider
    			ref="authService" />
    	</security:authentication-manager>
    
    	<bean id="authService" class="ro.test.services.BasicAuthenticationProvider" />
    - the login.jsp file contains:
    HTML Code:
    <form:form method="post"
    			action="j_spring_security_check" modelAttribute="loginBean">
    
    			<font color="red"><form:errors path="*" /></font>
    			<br />
    			Name: <form:input path="j_username" />
    			<br />
    			Password: <form:password path="j_password" />
    			<br />
    			<input type="submit" value="Login" />
    		</form:form>
    - I also have a login controller in which I intend to perform the custom validation; however, this is the tricky part for me:
    Code:
    @Controller
    @SessionAttributes("loginBean")
    public class LoginController {
    
    	private LoginValidator validator;
    
    	@Autowired
    	public LoginController(LoginValidator validator) {
    		this.validator = validator;
    	}
    
    	@RequestMapping(value = "/login", method = RequestMethod.GET)
    	public String doGet(Model model) {
    		LoginBean bean = new LoginBean();
    		model.addAttribute("loginBean", bean);
    		return "login";
    	}
    
    	@RequestMapping(value = "/login", method = RequestMethod.POST)
    	public String doPost(@ModelAttribute LoginBean bean, BindingResult result) {
    		validator.validate(bean, result);
    		if (result.hasErrors()) {
    			return "login";
    		} else {
    			return "/j_spring_security_check";
    		}
    	}
    }
    - the problem is that I do not know what to do when the validator says "ok, no validation error" - how can I return the control to the normal Spring Security processing (in the above example I have tried returning to the "j_spring_security_check" view - but no chance).

    Do you have any ideas about how to do this?

    PS: I also have an AuthenticationProvider which seems to do the job properly when I use normal Security flow without trying to do validations inside the controller.

    Thanks in advance!

    Regards,
    Daniel

  • rohan123
    replied
    Kajal be a part of this and bring it to different level,
    Best luck

    Leave a comment:


  • kajal123
    replied
    Hello Guys....... My self kajal here........... I'm new member of this forum.
    its my pleasure to be a part of this beautiful peoples community.


    regards.







    Vastu |Monthly Forecast| Acupressure |Vastu shastra

    Leave a comment:


  • nivas_spring
    replied
    Hi.
    I did custom userdetailservice. I hope this will help you.

    My security.xml:
    Code:
    <global-method-security secured-annotations="enabled">
    </global-method-security>
    <http auto-config="false" access-denied-page="/accessDenined.jsp">
     	<intercept-url pattern="/web/**" access="ROLE_ADMIN,ROLE_USER"/>
       	<intercept-url pattern="/web/admin/logFailure" filters="none" />
       	<form-login login-page="/login.jsp" authentication-failure-url="/web/admin/logFailure"
        	default-target-url="/web/admin/logSucess"   
        	always-use-default-target="true" />
       	<logout logout-success-url="/login.jsp?logout=true" />
    </http>
    <authentication-provider user-service-ref="customUserDetailService" />
    Custom User Detail Service Been in application-config.xml:

    Code:
    <bean id="customUserDetailService" class="com.programmarstamil.www.controller.MyUserDetailsService">
        	<property name="dataSource" ref="dataSource" />
        </bean>
    Custom User Service Implemented Class:
    Code:
    public class MyUserDetailsService implements UserDetailsService{
    	private DataSource dataSource;
    	@Override
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException, DataAccessException {
    		// TODO Auto-generated method stub
    		String sql = "select * from users where username like :username";
    		MapSqlParameterSource source = new MapSqlParameterSource();
    		source.addValue("username", username);
    		SimpleJdbcTemplate sjt = new SimpleJdbcTemplate(getDataSource());
    		User user = sjt.queryForObject(sql, new UserMapper(), source);
    		return user;
    	}
    	public DataSource getDataSource() {
    		return dataSource;
    	}
    	public void setDataSource(DataSource dataSource) {
    		this.dataSource = dataSource;
    	}
    	public GrantedAuthority[] getAuthorities(boolean isAdmin){
    		List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);
    		authList.add(new GrantedAuthorityImpl("ROLE_USER"));
    		if(isAdmin){
    			authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
    		}
    		return authList.toArray(new GrantedAuthority[]{});
    	}
    	public class UserMapper implements ParameterizedRowMapper<User>{
    
    		@Override
    		public User mapRow(ResultSet rs, int arg1) throws SQLException {
    			// TODO Auto-generated method stub
    			return new User(rs.getString("username"),rs.getString("password"),true,true,true,true,getAuthorities(rs.getBoolean("admin")));
    		}
    		
    	}
    
    }
    Also Handler:
    Code:
    @Controller
    public class AdminController {	
    	public AdminController(){
    		
    	}	
    	@RequestMapping(method=RequestMethod.GET)
    	public void logFailure(Model model){		
    		model.addAttribute("failureMessage","Please Provide Correct Information");
    	}
    	@RequestMapping(method=RequestMethod.GET)
    	public String logSucess(Principal user){
    		return "redirect:secured";
    	}
    }
    In view

    Code:
    <c:if test='${not empty failureMessage}'>
           <div class="error">
    	   <div class="message error" >
    	       <strong>Login failed:</strong> | <span>${failureMessage}</span>
    	   </div>
          </div>
    </c:if>

    Leave a comment:


  • rohan123
    replied
    hey dbutler
    It can be done like that and you can throw exception from that service in case of validation

    Leave a comment:


  • dbutler
    replied
    Originally posted by antispam View Post
    As I said: I need to do custom validation (eg: verify if the user exists in the DB). Is this possible?l
    How about implementing your own UserDetailsService and overriding the loadUserByUsername method? You can then write your own dao class so you can query the necessary tables in the DB

    The loadUserByUsername must return an object that implements UserDetails

    HTH

    Leave a comment:


  • rohan123
    replied
    Hey AntiSpam and marioosh, Spring Security already provide what both u want, just read Spring Security Doc carefully,

    Leave a comment:


  • marioosh
    replied
    antispam, did You solve Your problem? I'm working on the same approach.

    Leave a comment:


  • antispam
    replied
    As I said: I need to do custom validation (eg: verify if the user exists in the DB). Is this possible?

    Regards,
    Daniel

    Leave a comment:


  • dbrinker
    replied
    Actually, there's no need for a LoginController - the login message (POST to j_spring_security_check) is completely handled by Spring Security. This includes login processing, handling the response based on success or failure, etc.

    Hope this helps
    - Don

    Leave a comment:

Working...
X