realm:
@Slf4j
public class UserRealm extends AuthorizingRealm {
@Autowired
private IInowRoleUserService roleUserService;
@Autowired
private IInowRoleService roleService;
@Autowired
private IInowUserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
log.info("=========执行了授权===========================");
InowUser userName = (InowUser) principalCollection.getPrimaryPrincipal();
InowUser inowUser = userService.selectOneByName(userName.getUserName());
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
final InowRoleUser roleuser = roleUserService.getOne(new LambdaQueryWrapper<InowRoleUser>().eq(InowRoleUser::getUserId, inowUser.getUserId()));
List<String> inowRoleList = new ArrayList<>();
inowRoleList.add(roleService.getOne(new LambdaQueryWrapper<InowRole>().eq(InowRole::getId,roleuser.getRoleId())).getRoleName());
simpleAuthorizationInfo.addRoles(inowRoleList);
//添加用户角色,用于@requireroles注解
return simpleAuthorizationInfo;
}
@Override
public boolean supports(AuthenticationToken token) {
// return token instanceof JWTToken;
// return token instanceof UsernamePasswordToken;
return true;
}
@Autowired
private IInowUserService iInowUserService;
@Autowired
private InowLoginService inowLoginService;
/**
* 登录认证
*/
//仅为登录的简单版本,还未进行错误校验和sessionDAO记录等等
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
log.info("执行了登录认证");
//MyUsernamePasswordToken myUsernamePasswordToken = (MyUsernamePasswordToken) authenticationToken;
UsernamePasswordToken myUsernamePasswordToken = (UsernamePasswordToken) authenticationToken;
// String userId = myUsernamePasswordToken.getUserId();
String userName = myUsernamePasswordToken.getUsername();
String userId = String.valueOf(myUsernamePasswordToken.getPassword());
InowUser user = null;
// InowUser inowUser = iInowUserService.selectOneByName(userName);
try
{
user = inowLoginService.login(userName,userId);
}
catch (UnknownAccountException e)
{
throw new UnknownAccountException(e.getMessage(), e);
}
catch (IncorrectCredentialsException e)
{
throw new IncorrectCredentialsException(e.getMessage(), e);
}
Session session = new SimpleSession();
session.setAttribute("user",user);
return new SimpleAuthenticationInfo(user,user.getUserId(),userName);
}
}
config:
@Configuration
//@EnableAspectJAutoProxy(exposeProxy = true)
public class ShiroConfig {
public logOutFilter mylogoutFilter()
{
logOutFilter MylogoutFilter = new logOutFilter();
MylogoutFilter.setLoginUrl("login");//设置退出后重定向的跳转地址
return MylogoutFilter;
}
/**
* 注入Shiro过滤器链配置
* 注入安全服务配置
* 注入自定义jwt过滤器
*
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Autowired @Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager,
@Autowired ShiroFilterChainDefinition definition,
@Autowired JWTFilter jwtFilter){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);//设置安全管理器
//可以添加shiro的内置过滤器
//anon:无需认证就可以访问 authc:必须认证了才能用 oerms:拥有对某个资源的权限才能访问
bean.setLoginUrl("/login");//设置登录路径
Map<String,String> map = new HashMap<>();
map.put("/login","anon");
bean.setFilterChainDefinitionMap(map);
Map<String, Filter> filterMap = new HashMap<>();
// 注销成功,则跳转到指定页面
filterMap.put("logout", mylogoutFilter());
bean.setFilters(filterMap);
// bean.setFilterChainDefinitionMap(definition.getFilterChainMap());
return bean;
}
/**
* 自定义jwt过滤器
*
* @return
*/
@Bean
public JWTFilter jwtFilter(){
return new JWTFilter();
}
/**
* 定义拦截器链,所有请求都经过自定义的jwt过滤器
*
* @return
*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
Map<String,String> map = new LinkedHashMap<>();
map.put("/swagger-ui.html","anon");
map.put("/**","jwt");
definition.addPathDefinitions(map);
return definition;
}
/**
* 自定义Realm
*
* @return
*/
@Bean
public UserRealm myUserRealm(){
UserRealm userRealm = new UserRealm();
return userRealm;
}
/**
* 开启认证授权注解
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Autowired DefaultWebSecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean("securityManager")
public DefaultWebSecurityManager securityManager(@Autowired UserRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")
DefaultWebSecurityManager manager)
{
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(manager);//设置安全管理器
//可以添加shiro的内置过滤器
//anon:无需认证就可以访问 authc:必须认证了才能用 oerms:拥有对某个资源的权限才能访问
bean.setLoginUrl("/login");
配置不会被拦截的链接 顺序判断
Map<String,String> map = new HashMap<>();
map.put("/login","anon"); //开放登录接口
map.put("/user/add","anon");
map.put("/user/update","authc");
map.put("/login/update","authc");
map.put("/0.png","anon");
bean.setFilterChainDefinitionMap(map);
return bean;
}
@Bean
public Mapper mapper() {
return new DozerBeanMapper();
}
}
退出过滤器
package com.inow.dachuang2021.shiro;
import com.inow.dachuang2021.entity.manager.InowUser;
import com.inow.dachuang2021.utils.ManagerUtils.ShiroUtils;
import freemarker.template.utility.StringUtil;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.Objects;
/**
* @Author
* @Description 用户退出过滤器 继承shiro的LogoutFilter
* @Date 11.2
**/
public class logOutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter{
private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class);
/**
* 退出后重定向的地址
*/
private String loginUrl;
public String getLoginUrl()
{
return loginUrl;
}
public void setLoginUrl(String loginUrl)
{
this.loginUrl = loginUrl;
}
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception
{
try
{
Subject subject = getSubject(request, response);
String redirectUrl = getRedirectUrl(request, response, subject);
try
{
InowUser user = ShiroUtils.getSysStudent();
if (Objects.nonNull(user))
{
String loginName = user.getUserName();
// 记录用户退出日志
// AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
// 清理缓存
// SpringUtils.getBean(ISysUserOnlineService.class).removeUserCache(loginName, ShiroUtils.getSessionId());
}
// 退出登录
subject.logout();
}
catch (SessionException ise)
{
log.error("logout fail.", ise);
}
issueRedirect(request, response, redirectUrl);
}
catch (Exception e)
{
log.error("Encountered session exception during logout. This can generally safely be ignored.", e);
}
return false;
}
/**
* 退出跳转URL
*/
@Override
protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject)
{
log.info("===============执行了退出重定向=====================");
String url = getLoginUrl();
if (Objects.nonNull(url))
{
return url;
}
return super.getRedirectUrl(request, response, subject);
}
}