您的位置:首页 > 编程语言 > Java开发

登录出错不过3,结合springsec

2015-08-19 17:29 816 查看
原文

点击打开链接

1.整个Demo



2.security配置

package com.pack.samples.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier(value = "authenticationProvider")
public AuthenticationProvider authenticationProvider;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}

@Override
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_USER')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout").and().csrf();
}

}

3.实现UserDetailsService接口

package com.pack.samples.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;
import org.springframework.stereotype.Service;

/**
* Reference org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl
*
* @author mkyong
*
*/
@Service("userDetailsService")
public class CustomUserDetailsService extends JdbcDaoImpl {

@Autowired
private DataSource dataSource;

@PostConstruct
private void initialize() {
setDataSource(dataSource);
}

@Override
@Value("select * from users where username = ?")
public void setUsersByUsernameQuery(String usersByUsernameQueryString) {
super.setUsersByUsernameQuery(usersByUsernameQueryString);
}

@Override
@Value("select username, role from user_roles where username =?")
public void setAuthoritiesByUsernameQuery(String queryString) {
super.setAuthoritiesByUsernameQuery(queryString);
}

//override to get accountNonLocked
@Override
public List<UserDetails> loadUsersByUsername(String username) {
return getJdbcTemplate().query(super.getUsersByUsernameQuery(), new String[] { username },
new RowMapper<UserDetails>() {
public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
String username = rs.getString("username");
String password = rs.getString("password");
boolean enabled = rs.getBoolean("enabled");
boolean accountNonExpired = rs.getBoolean("accountNonExpired");
boolean credentialsNonExpired = rs.getBoolean("credentialsNonExpired");
boolean accountNonLocked = rs.getBoolean("accountNonLocked");

return new User(username, password, enabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, AuthorityUtils.NO_AUTHORITIES);
}

});
}

//override to pass accountNonLocked
@Override
public UserDetails createUserDetails(String username, UserDetails userFromUserQuery,
List<GrantedAuthority> combinedAuthorities) {
String returnUsername = userFromUserQuery.getUsername();

if (super.isUsernameBasedPrimaryKey()) {
returnUsername = username;
}

return new User(returnUsername, userFromUserQuery.getPassword(), userFromUserQuery.isEnabled(),
userFromUserQuery.isAccountNonExpired(), userFromUserQuery.isCredentialsNonExpired(),
userFromUserQuery.isAccountNonLocked(), combinedAuthorities);
}

}


3.最重要的是DaoAuthenticationProvider的实现类,他调用了UserDetailsDaoImpl处理了3次登录失败的逻辑,不过感觉不怎么好的是,作者把逻辑放在了UserDetailsDaoImpl即DAO的层次

package com.pack.samples.web.handler;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import com.pack.samples.dao.UserDetailsDao;
import com.pack.samples.model.UserAttempts;

@Component("authenticationProvider")
public class LimitLoginAuthenticationProvider extends DaoAuthenticationProvider {

@Autowired
UserDetailsDao userDetailsDao;

@Autowired
@Qualifier("userDetailsService")
@Override
public void setUserDetailsService(UserDetailsService userDetailsService) {
super.setUserDetailsService(userDetailsService);
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

try {

Authentication auth = super.authenticate(authentication);

//if reach here, means login success, else exception will be thrown
//reset the user_attempts
userDetailsDao.resetFailAttempts(authentication.getName());

return auth;

} catch (BadCredentialsException e) {

//invalid login, update to user_attempts
userDetailsDao.updateFailAttempts(authentication.getName());
throw e;

} catch (LockedException e){

//this user is locked!
String error = "";
UserAttempts userAttempts = userDetailsDao.getUserAttempts(authentication.getName());
if(userAttempts!=null){
Date lastAttempts = userAttempts.getLastModified();
error = "User account is locked! <br><br>Username : " + authentication.getName() + "<br>Last Attempts : " + lastAttempts;
}else{
error = e.getMessage();
}

throw new LockedException(error);
}

}

}


效果







下载

点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: