1.应用代码通过 Subject 来进行认证和授权,而 Subject 又委托给 SecurityManager;
2.我们需要给 Shiro 的 SecurityManager 注入 Realm,从而让 SecurityManager 能得到合法的用户及其权限进行判断。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
package com.hd.config;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
@Configuration
public class ShiroConfig {
/**
* 配置Shiro的Web过滤器,拦截浏览器请求并交给SecurityManager处理
* @return
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
/*
* 添加shiro内置过滤器:
* anon:无需认证
* authc:必须认证才可以访问
* user:如果使用remember的功能才可以访问
* perms:该资源必须得到资源权限才可以访问
* roles:该资源必须得到角色权限才可以访问
*/
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/img/**","anon");
filterChainDefinitionMap.put("/register.html","anon");
filterChainDefinitionMap.put("/public/login.html","anon");
filterChainDefinitionMap.put("/userlogin","anon");
filterChainDefinitionMap.put("/error/**","anon");
filterChainDefinitionMap.put("/findOne","anon");
//设置授权
filterChainDefinitionMap.put("/user/**","roles[admin]");
filterChainDefinitionMap.put("/**","authc");
//修改跳转页面
shiroFilterFactoryBean.setLoginUrl("/login.html");
//自定义授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth.html");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
* @param userRealm
* @return
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 创建realm
* @return 用户realm
*/
@Bean(name="userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
realm
package com.hd.config;
import com.hd.entity.Role;
import com.hd.entity.User;
import com.hd.service.UserService;
import org.apache.shiro.SecurityUtils;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权入口");
User user = (User) SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 获取用户权限
Role role = userService.findRoleByName(user.getName());
//todo:role=null ??
// 设置该用户拥有的权限
HashSet<String> roles = new HashSet<>();
roles.add(role.getRole_name());
info.setRoles(roles);
return info;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取用户名
String userName = (String)authenticationToken.getPrincipal();
// 查询有无该用户
User user = userService.findUserByName(userName);
if (null == user)
{
// 没有该用户
return null;
}
// 有该用户, 判断密码
/**
* 参数1: 从数据库获取的userduix
* 参数2: 密码
* 参数3: 当前realm名称
*/
return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
}
}
/**
* 登录验证
*
* @param username 用户名
* @param password 密码
* @param model
* @return
*/
@PostMapping(value = "/userlogin")
public String user_login(String username, String password, Model model){
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
Subject currentUser = SecurityUtils.getSubject();
try {
//主体提交登录请求到SecurityManager
currentUser.login(token);
}catch (IncorrectCredentialsException ice){
model.addAttribute("msg","密码不正确");
}catch(UnknownAccountException uae){
model.addAttribute("msg","账号不存在");
}catch(AuthenticationException ae){
model.addAttribute("msg","状态不正常");
}
if(currentUser.isAuthenticated()){
System.out.println("认证成功");
//model.addAttribute("currentUser", currentUser());
return "/rpdtester"; //todo:返回json,保存用户登录信息
}else{
token.clear();
return "/login.html";
}
}
原文:https://www.cnblogs.com/xiongyungang/p/12660466.html