1.pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
2.shiro配置
package com.knife.Shiro_Springboot;
import java.util.LinkedHashMap;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
@Configuration
public class Config {
@Bean(name="shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
System.err.println("---------------create shiroFilter------------------");
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
bean.setSecurityManager( manager);
//配置登录的url
bean.setLoginUrl("/login");
//配置访问权限
LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/check", "anon");
filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return bean;
}
//配置核心安全事务管理器
@Bean(name="securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
System.err.println("--------------shiro已经加载----------------");
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
manager.setRealm(authRealm);
return manager;
}
//配置自定义的权限登录器
@Bean(name="authRealm")
public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
AuthRealm authRealm=new AuthRealm();
authRealm.setCredentialsMatcher(matcher);
return authRealm;
}
//配置自定义的密码比较器
@Bean(name="credentialsMatcher")
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(manager);
return advisor;
}
}
3.自定义realm
package com.knife.Shiro_Springboot;
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class AuthRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
System.err.println("授权");
User user = getSessionUser(principals);// 获取session中的用户
List<String> permissions = user.getPermissions();
List<String> roles = user.getRoles();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);// 将权限放入shiro中.
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.err.println("登录");
// TODO Auto-generated method stub
UsernamePasswordToken utoken = (UsernamePasswordToken) token;// 获取用户输入的token
String username = utoken.getUsername();
char[] password = utoken.getPassword();
System.out.println("输入的用户名:" + username + " 输入的密码:" + password.toString());
User principals = getDbUser();// 原型
String credentials = principals.getPassword();// 证书
return new SimpleAuthenticationInfo(principals, credentials, this.getClass().getName());// 放入shiro.调用
}
// 模拟数据库取出的数据
private User getDbUser() {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
return user;
}
//从principals中取出数据
private User getSessionUser(PrincipalCollection principals) {
return (User) principals.fromRealm(this.getClass().getName()).iterator().next();
}
}
4.自定义代码对比器
package com.knife.Shiro_Springboot;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
public class CredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken utoken=(UsernamePasswordToken) token;
//获得用户输入的密码:(可以采用加盐(salt)的方式去检验)
String inPassword = new String(utoken.getPassword());
String inUsername = utoken.getUsername();
System.out.println("输入的用户名:"+inUsername+" 输入的密码:"+inPassword);
//获得数据库中的密码
User dbUser= (User)info.getPrincipals().fromRealm(AuthRealm.class.getName()).iterator().next();;
//User dbUser=(User) o;
//进行密码的比对
String dbusername = dbUser.getUsername();
String dbPassword = dbUser.getPassword();
System.out.println("系统的用户名:"+dbusername+" 系统的密码:"+dbPassword);
boolean result=equals(inPassword, dbPassword);
if(result)
System.out.println("SUCCESS");
else
System.out.println("FAILE");
return result;
}
}
5.web地址
@Autowired
SecurityManager securityManager;
@RequestMapping("home")
@ResponseBody
public String home(){
return "home";
}
@RequestMapping("login")
@ResponseBody
public String login(){
return "login";
}
@RequestMapping("logout")
@ResponseBody
public String logout(){
SecurityUtils.getSubject().logout();
return "login";
}
@RequestMapping("test")
@ResponseBody
public String test(){
return "test";
}
@RequestMapping("check")
@ResponseBody
public String login(User user){
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
try {
// 4、登录,即身份验证
subject.login(token);
return "home";
} catch (AuthenticationException e) {
// 5、身份验证失败
e.printStackTrace();
System.out.println(e.getMessage());
}
return "nopermission";
}
直接访问test会跳转至login,访问check登录成功跳转至home,此时可以访问test
6.权限
@RequiresRoles("admin")
@RequestMapping("testrole")
@ResponseBody
public String testrole(){
return "has role";
}
@RequiresPermissions("detail")
@RequestMapping("testpermission")
@ResponseBody
public String testpermission(){
return "has permission";
}
授权
// 模拟数据库取出的数据
private User getDbUser() {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
List<String> permission = new ArrayList<String>();
permission.add("detail");
user.setPermissions(permission);
List<String> roles = new ArrayList<String>();
roles.add("admin");
user.setRoles(roles);
return user;
}
授权后才可访问以上地址,否则无法访问