最近在最shiro的多入口登錄,搞了好久,就把spring security拿出來再炒一下,這是我以前在csdn寫過的一篇博客。
spring security 是一個權限控制的框架。可以很方便地實現權限的控制,不需要我們手動地寫攔截器去對於請求進行攔截,然后對於權限進行判斷。這可以大大地減少工作量,並且,spring security提供了很可靠的安全保障。
廢話不多說,以下為正文:
1、加入spring security的jar包,我是能過maven配合nexus進行jar包管理的。純jar包也是可以的,下載相應的jar包添加到WEB-INF下的lib目錄下即可。以下為pom.xml加入的依賴(來處官網http://projects.spring.io/spring-security/):
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
</dependencies>
2、在web.xml里面加入spring security的攔截器,當然配置文件也要加載,不過是通過正則表達式一次把spring的配置文件都加載完成的:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring*.xml </param-value> </context-param>
<!-- spring security --> <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>
3、配置spring-security.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<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.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- 不需要進行認證的資源,3.0之后才改為這樣配置 -->
<!-- <http security="none" pattern="/**/index" /> -->
<http security="none" pattern="/**/login" />
<http security="none" pattern="/**/*.jpg" />
<http security="none" pattern="/**/*.png" />
<http security="none" pattern="/**/*.gif" />
<http security="none" pattern="/**/*.css" />
<http security="none" pattern="/**/*.js" />
<!--設置匹配學生用戶url,登錄頁面和所擁有的權限,以及引用studentAuthManager驗證管理 -->
<http auto-config="true" pattern="/student/**" use-expressions="true" authentication-manager-ref="studentAuthManager">
<form-login login-processing-url="/student/j_spring_security_check"
login-page="/student/login" authentication-failure-url="/student/login" default-target-url="/student/index"/>
<logout logout-success-url="/student/login" logout-url="/student/j_spring_security_logout" />
<intercept-url pattern="/student/**" access="hasRole('ROLE_STUDENT')" />
</http>
<!--設置匹配管理員用戶url,登錄頁面和所擁有的權限,以及引用adminAuthManager驗證管理 -->
<http auto-config="true" pattern="/admin/**" use-expressions="true" authentication-manager-ref="adminAuthManager">
<form-login login-processing-url="/admin/j_spring_security_check"
login-page="/admin/login" authentication-failure-url="/admin/login" default-target-url="/admin/index"/>
<logout logout-url="/admin/j_spring_security_logout" logout-success-url="/admin/index" />
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
</http>
<!--前台用戶驗證管理bean -->
<authentication-manager id="studentAuthManager">
<authentication-provider user-service-ref="studentDetailService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
</authentication-manager>
<!--后台管理用戶驗證管理bean -->
<authentication-manager id="adminAuthManager">
<authentication-provider user-service-ref="adminDetailService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
</authentication-manager>
</beans:beans>
4、重寫實現UserDetailsService的接口(由於student的實現方式,跟admin的實現方式是一模一樣的,所以此處只列出admin的例子):
@Service
public class AdminDetailService implements UserDetailsService{
@Resource
private AdminMapper adminMapper;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Admin admin = adminMapper.selectByUsername(username);
return admin;
}
}
5、在Admin的實體實現UserDetails接口(由於僅為demo所以權限是寫死了的,可以從數據庫取出),student實現也是實現UserDetails接口,不重復貼代碼了。
public class Admin implements UserDetails{
private static final long serialVersionUID = 1557391641237960295L;
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
//此部分的權限應該由數據庫取出,此處不作取出操作
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return authorities;
}
public void setPassword(String password){
this.password = password;
}
public void setUsername(String username){
this.username = password;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
public boolean isAccountNonExpired() {
return true;
}
public boolean isAccountNonLocked() {
return true;
}
public boolean isCredentialsNonExpired() {
return true;
}
public boolean isEnabled() {
return true;
}
}
6、如果不寫頁面的話,spring security會使用它默認的頁面,十分的丑陋,不過所幸可以自己寫,以下為自己寫的頁面(也十分地丑陋):
<body>
<form action="j_spring_security_check" method="post">
username:<input type="text" name="j_username"/><br/>
password:<input type="password" name="j_password"/><br/>
Remember Me:<input name="_spring_security_remember_me" type="checkbox" value="true"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
7、訪問,登錄,大功告成,由於此部分的代碼由項目代碼改的,所以沒有demo不好意思!!!(有機會一定補上= =||,估計是補不上了)
