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

  • 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

  • #2
    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

    Comment


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

      Regards,
      Daniel

      Comment


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

        Comment


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

          Comment


          • #6
            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

            Comment


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

              Comment


              • #8
                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>

                Comment


                • #9
                  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

                  Comment


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

                    Comment

                    Working...
                    X