自定义数据源的用户权限验证
Spring Security框架提供的基于角色的权限验证,能够解决大部分业务场景的权限问题。但真实的业务场景大部分都是动态的用户,比如说可能会有新用户注册进来,而新用户也要分配相应的角色权限,并且权限的用户名和密码也是用户自定义的,这就要求Spring Security框架能够提供动态的用户信息验证。
前面就说过了,Spring Security具有极高的扩展性,为使用者抽象出了数据源提供器,也就是authentication-provider配置,可能此配置可以实现使用者自定义的数据源,然后Spring Security的低层就可以根据自定义的数据源获取数据进行信息验证。
下面就是实现UserDetailService接口定义自己的数据源,来动态地进行用户信息验证,在自定义的数据源中,可以连接数据库,从数据库中读取用户信息,在此为了简洁,仅用"死"代码来演示。
<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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<beans:bean id="successHandler" class="security.controller.AuthoritySuccessHandler" />
<beans:bean id="customeUserDetailService" class="security.controller.CustomeUserDetailService"/>
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/dba**" access="hasRole('ROLE_DBA')" />
<intercept-url pattern="/user**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/index"
authentication-failure-url="/login?error" username-parameter="username"
password-parameter="password" authentication-success-handler-ref="successHandler" />
<logout logout-success-url="/login?logout" />
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="customeUserDetailService"/>
</authentication-manager>
</beans:beans>
security配置文件只需改成上面就好,下面的代码是CustomeUserDetailService的具体实现
package security.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service("customeUserDetailService")
public class CustomeUserDetailService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println(username);
String password = getPasswordByUsername(username);
System.out.println(password);
if (password == null) {
throw new UsernameNotFoundException("username " + username + " not found");
}
User user = new User(username, password, true, true, true, true, getGrantedAuthorities(username));
return user;
}
private String getPasswordByUsername(String username) {
if ("dba".equals(username)) {
return "123456";
} else if ("user".equals(username)) {
return "654321";
}
return null;
}
private List<GrantedAuthority> getGrantedAuthorities(String username) {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
if ("dba".equals(username)) {
list.add(new SimpleGrantedAuthority("ROLE_DBA"));
} else if ("user".equals(username)) {
list.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return list;
}
}
在这个类中,可以把相应的验证逻辑代码替换成数据库查询后再验证来实现真正的动态验证。然后运行项目,就可以实现和前面一样的效果,并且还是动态用户信息验证的。