以下原因:
1.realmConfig方法未加@Bean, 可以在ShiroConfig类每个方法都加上@Bean
@Bean(name = "realmConfig")
public RealmConfig realmConfig() {
return new RealmConfig();
}
2.ShiroConfig中使用到RealmConfig类对象的方法, 必须使用(@Qualifier(“realmConfig”) RealmConfig realmConfig作为方法的参数
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realmConfig")
RealmConfig realmConfig) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realmConfig);
return securityManager;
}
//权限管理 特别是这里, 原先我写的是dsm.setRealm(new RealmConfig());
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("realmConfig")RealmConfig realmConfig ) {
DefaultWebSecurityManager dsm = new DefaultWebSecurityManager();
//自定义验证方式
dsm.setRealm(realmConfig);
//记住我
dsm.setRememberMeManager(cookieRememberMeManager());
return dsm;
}
ShiroConfig类完整代码如下
@Configuration
public class ShiroConfig {
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAPC = new DefaultAdvisorAutoProxyCreator();
defaultAAPC.setProxyTargetClass(true);
return defaultAAPC;
}
//配置cookie基础属性
@Bean
public SimpleCookie simpleCookie() {
SimpleCookie sc = new SimpleCookie("rememberMe");
//cookie有效时间 单位秒 以下设置了30天
sc.setMaxAge(30 * 24 * 60 * 60);
return sc;
}
//cookie管理器
@Bean
public CookieRememberMeManager cookieRememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(simpleCookie());
// cookieRememberMeManager.setCipherKey用来设置加密的Key,参数类型byte[],字节数组长度要求16
cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
//权限管理
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("realmConfig")RealmConfig realmConfig ) {
DefaultWebSecurityManager dsm = new DefaultWebSecurityManager();
//自定义验证方式
dsm.setRealm(realmConfig);
//记住我
dsm.setRememberMeManager(cookieRememberMeManager());
return dsm;
}
/**
* ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(
@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
Map<String, String> maps = new LinkedHashMap<>();
// maps.put("/add","anon"); // /add"被所有人都能访问
// maps.put("/update","authc"); // /update"被所有人都能访问
//授权,访问/user/**"必须拥有权限user:add
// maps.put("/user/**","perms[user:add]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(maps);
/*
* anon:无需认证就可以访问
* authc: 必须认证了才可以访问
* user:必须拥有 记住我 功能才可以访问
* perms: 拥有对某个资源的权限才可以访问
* role: 拥有某个角色权限才可以访问
* */
//设置登录的login页面
shiroFilterFactoryBean.setLoginUrl("/page/login");
//设置未授权之后跳转的页面
shiroFilterFactoryBean.setUnauthorizedUrl("");
return shiroFilterFactoryBean;
}
/**
* DefaultWebSecurityManager
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realmConfig")
RealmConfig realmConfig) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realmConfig);
return securityManager;
}
/**
* 创建realm对象
*/
@Bean(name = "realmConfig")
public RealmConfig realmConfig() {
return new RealmConfig();
}
}
RealmConfig类完整代码如下
public class RealmConfig extends AuthorizingRealm {
@Override //授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权:AuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermission("user:add"); //给用户添加一个权限
//获取当前对象
Subject subject = SecurityUtils.getSubject();
// 获取当前对象所对应的用户
Users user = (Users) subject.getPrincipal();
info.addStringPermission(user.getPasword());
return info;
}
@Autowired
UsersServiceImpl userService;
@Override //认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证请求: " + userService);
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//我这里是通过username查id
if (userToken.getUsername() == null) {
return null;
}
// 从数据库中取到
Users users = userService.selectByUsername(userToken.getUsername());
if (users == null || users.getStatus().equals("1")) {
//用户不存在或还未激活
return null;
}
//密码认证,Shiro自动做,这里第一个参数是什么,在进行强制类型转化Users user = (Users)subject.getPrincipal();的时候就是是什么类型
return new SimpleAuthenticationInfo(users, users.getPasword(), "");
//第一个principal属性-->user代表把user用户对象放进当前对象中,第二个是密码,会帮你自动验证密码
}
}