在很多面试的时候都会问道“做没做过权限管理”,那么什么是权限管理?刚开始我只知道是不是就是一个字段0或1来表示用户的等级呢?当时感觉没什么不对,可后来发现是错的很离谱,估计已经在考官面前得到了一个定义了。
spring security 一个成熟的安全管理框架,很多资料上都说spring security有弊病,其中说的是系统的角色都要配置在文件里,也就是说在系统之前要先定义角色,以后想再添加新角色是麻烦要改的,还有一些干脆说只能配置在配置文件里,那么我想说的是,那是那些写文章的不了解,当让我可能也有错误,因为刚接触可能有一些不了解却自以为了解的知识。
那么我感觉spring security中比较常用也是比较重要的功能就是对url资源的权限管理以及对方法级别的权限管理
首先我们先要下载最新版本的spring security开发包,下载完以后会在dist文件目录下看见有两个。war结尾的工程包,解压以后会得到里面的例子工程,但这只是一个比较简单的配置,自己看看就可以了,因为那个太简单了,没什么意义。 把例子项目里的jar拿出来,这是你自己要用的。
首先在web。xml中加入一个监听器来启动spring security的过滤器链。在spring的配置文件中配置spring security
web。xml中加入
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
意思是过滤所有的连接
applicationContext。xml中 加入
<http access-denied-page="/error.jsp" auto-config="true"
use-expressions="true">
<form-login login-page="/login.jsp"
always-use-default-target="true" authentication-failure-url="/login.jsp?login_error=1"
default-target-url="/servlet/LoginServlet" />
<intercept-url pattern="/login.jsp" access="permitAll" />
<logout logout-success-url="/login.jsp"/>
<intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_NORMAL')" />
<http-basic />
<!-- 防止重复登录-->
<session-management invalid-session-url="/sessionOuttime.jsp">
<!-- 只能有一个登录,第二个将会替代第一个 -->
<concurrency-control max-sessions="1"/>
<!-- 防止第二次登录 <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>-->
</session-management>
</http>
那么在配置文件中配置角色大家都可以找到各种资料,我在这里就不配置了。我主要给大家讲一下在数据库中定义角色。
<authentication-manager>
<authentication-provider user-service-ref="userService">
<!--
<user-service> <user name="user" password="user"
authorities="ROLE_USER" /> </user-service> <password-encoder
hash="md5" /> <jdbc-user-service data-source-ref="dataSource" />
-->
</authentication-provider>
</authentication-manager>
在这里配置一个认证管理器。
那么想在系统过滤的时候使用自己的过滤器就需要,自己去实现借口了。那么我没只要实现UserDetailsService这个借口和UserDetails这个借口
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class UserService implements UserDetailsService {
private UserDao dao;
public UserDetails loadUserByUsername(String name)
throws UsernameNotFoundException {
User user = dao.getRoleByName(name);
if (user == null) {
throw new UsernameNotFoundException("UserName not find");
}
return user;
}
public void setDao(UserDao dao) {
this.dao = dao;
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
public class User implements UserDetails {
private String uuid;
private String username;
private String password;
private char isVaild;
private List<Role> roles;
//省略get set方法
@SuppressWarnings("deprecation")
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> list=new ArrayList<GrantedAuthority>();
for(Role role:roles){
list.add(new GrantedAuthorityImpl(role.getRoleName()));
}
return list;
}
public String getPassword() {
// TODO Auto-generated method stub
return this.password;
}
public String getUsername() {
// TODO Auto-generated method stub
return this.username;
}
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
public boolean isEnabled() {
// TODO Auto-generated method stub
return this.isVaild==0?false:true;
}
}
那么我们就可以自己写一个dao到数据库去取出user对象了,这样就可以对应自己的数据库了。
而在对方法级别的权限管理就相对简单很多
<!-- 启用注解
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled">
</global-method-security>
-->
<!-- 表达式方式配置鉴权 -->
<global-method-security>
<protect-pointcut access="ROLE_NORMAL" expression="(* *.test*(**))"/>
</global-method-security>
public class AnnotationsTest {
加上这两个配置就可以了,一个是配置用注解,一个是表达式,自己选择把!!!!!!
写的不好就写到这吧,有什么问题可以留言,有什么 建议也留言,因为我也不太了解spring security的具体之间的调用,希望大家交流!!!!!!!!!