@Configuration
public class ShiroConfig {
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilterBean(
@Qualifier("securityManager") SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 如果不设置默认会自动寻找Web工程根目录下的"/login"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("index/index.html");
//拦截器.
Map filterChainDefinitionMap = new LinkedHashMap();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/common/**", "anon");
filterChainDefinitionMap.put("/favicon.ico", "anon");
filterChainDefinitionMap.put("/error/**", "anon");
// 配置退出 过滤器,其中的具体的退出代码Shiro已经实现了
filterChainDefinitionMap.put("/logout", "logout");
//:这是一个坑呢,一不小心代码就不好使了;
//
filterChainDefinitionMap.put("/**", "authc");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(@Qualifier("communityRealm") CommunityRealm realm, @Qualifier("userDao")UserDao userDao) {
realm.setUserDao(userDao);
// realm.setCredentialsMatcher();
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean("communityRealm")
public CommunityRealm communityRealm(){
CommunityRealm communityRealm = new CommunityRealm();
return communityRealm;
}
}
注意,经再三验证,这里有个bug,如果没有配置这句
filterChainDefinitionMap.put("/", "anon");
那么shiro在用户登录退出之后,之后再登陆就不会自动跳转到设置好的index页面。
由于配置了上面的这个链接,即可以访问 http://主机名:端口/,所以需要做相应的配置,因此在loginController里面需要配置,如下:
@Controller
public class LoginController {
/**
* 圈子首页,登录页面
* @return
*/
@GetMapping("/")
public String index() {
return "login/login";
}
/**
* 认证
* @return
*/
@RequestMapping("/login")
public String login(HttpServletRequest request) throws Exception{
// shiro在认证过程中出现错误后将异常类路径通过request返回
String exceptionClassName = (String) request
.getAttribute("shiroLoginFailure");
// 登陆有错误,继续跳转登陆页面
if(exceptionClassName != null){
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
throw new Exception("账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(
exceptionClassName)) {
throw new Exception("用户名/密码错误");
} else if("randomCodeError".equals(exceptionClassName)){
throw new Exception("验证码错误");
} else{
// throw new Exception();//最终在异常处理器生成未知错误
}
return "login/login";
}
Subject subject = SecurityUtils.getSubject();
// 没有登陆
if (subject == null || !subject.isAuthenticated()) {
return "login/login";
}
return "index/index";
}
}
最后,自定义一个用于验证shiro用户认证 和 授权的realm,这里暂时只实现了realm的认证,代码如下:
public class CommunityRealm extends AuthorizingRealm {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (this.userDao == null) {
return null;
}
String usercode = (String) token.getPrincipal();
User user = userDao.findUserByUsercode(usercode);
if (user == null) {
return null;
}
SimpleAuthenticationInfo simpleAuthenticationInfo
= new SimpleAuthenticationInfo(user,user.getPassword(),"communityRealm");
return simpleAuthenticationInfo;
}
}
如果,有爱好java或者springboot项目的,欢迎加入群交流431445096