前后端分离Springboot整合shiro|前后端分离Springboot整合shiro -- 01基础使用

引入jar

org.apache.shiro shiro-spring 1.4.0

继承AuthorizingRealm 编写自己的doGetAuthorizationInfo()和doGetAuthenticationInfo()方法
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.iretailer.model.User; import com.iretailer.service.UserService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * @author xjwtt * @date 2018/9/26 */ public class ShiroRealm extends AuthorizingRealm { @Autowired private UserService userService; /** * 获取用户的角色和权限 * * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /** * 登录认证 * * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { /** * 获取输入的用户名和密码 */ String userName = (String) authenticationToken.getPrincipal(); User user = userService.getOne(new QueryWrapper().lambda().eq(User::getUsercode, userName)); if (user == null) { throw new UnknownAccountException("用户名或密码错误!"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getUserpwd(), getName()); return info; } }

配置ShiroConfig
import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import java.util.LinkedHashMap; /** * @author xjwtt * @date 2018/9/26 */ @Configuration public class ShiroConfig {/** * ShiroFilterFactoryBean 为Shiro过滤器工厂类 * 配置一些过滤路径 * @param securityManager * @return */ @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置 shiroFilterFactoryBean.setSecurityManager(securityManager); //配置shiro默认登录界面地址,前后端分离中登录界面跳转由端控制,后台仅返回json数据 shiroFilterFactoryBean.setLoginUrl("/unauth.action"); // 登录成功后跳转的url //shiroFilterFactoryBean.setSuccessUrl("/index"); // 未授权url //shiroFilterFactoryBean.setUnauthorizedUrl("/403"); LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>(); //注意过滤器配置顺序 不能颠倒 // 配置退出过滤器,其中具体的退出代码Shiro已经替我们实现了 //前后端分离自己实现 //filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/login.action", "anon"); filterChainDefinitionMap.put("/", "anon"); //解析不需要认证 filterChainDefinitionMap.put("/resolve", "anon"); // 需要认证的url filterChainDefinitionMap.put("/**.action", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }/** * SecurityManager 为shiro安全管理器,管理着所有的Subject * * @return */ @Bean public SecurityManager securityManager() { //配置 SecurityManager 并注入 shrioRealm DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); return securityManager; }/** * 引入自己实现的 ShiroRealm * * @return */ @Bean public ShiroRealm shiroRealm() { ShiroRealm shiroRealm = new ShiroRealm(); shiroRealm.setCredentialsMatcher(matcher()); return shiroRealm; }/** * 设置加密算法 * @return */ @Bean public HashedCredentialsMatcher matcher() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("md5"); //设置加密算法 matcher.setHashIterations(1); //设置加密算法的次数 return matcher; }}

注意filterChain基于短路机制,即最先匹配原则如:
/user/**=anon /user/aa=authc 永远不会执行

anon、authc等为Shiro实现的过滤器,具体如下
Filter Name Class Description
anon org.apache.shiro.web.filter.authc.AnonymousFilter 匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤;示例/static/**=anon
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 基于表单的拦截器;如/**=authc,如果没有登录会跳到相应的登录页面登录
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter Basic HTTP身份验证拦截器
logout org.apache.shiro.web.filter.authc.LogoutFilter 退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/),示例/logout=logout
noSessionCreation org.apache.shiro.web.filter.session.NoSessionCreationFilter 不创建会话拦截器,调用subject.getSession(false)不会有什么问题,但是如果subject.getSession(true)将抛出DisabledSessionException异常
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter 权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例/user/**=perms["user:create"]
port org.apache.shiro.web.filter.authz.PortFilter 端口拦截器,主要属性port(80):可以通过的端口;示例/test= port[80],如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter rest风格拦截器,自动根据请求方法构建权限字符串;示例/users=rest[user],会自动拼出user:read,user:create,user:update,user:delete权限字符串进行权限匹配(所有都得匹配,isPermittedAll)
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter 角色授权拦截器,验证用户是否拥有所有角色;示例/admin/**=roles[admin]
ssl org.apache.shiro.web.filter.authz.SslFilter SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口443;其他和port拦截器一样;
user org.apache.shiro.web.filter.authc.UserFilter 用户拦截器,用户已经身份验证/记住我登录的都可;示例/**=user
跨域以及静态资源处理
import org.springframework.context.annotation.Configuration; import org.springframework.util.ResourceUtils; import org.springframework.web.servlet.config.annotation.*; import java.io.File; /** * 配置 静态资源加载的路径 * 跨域CORS配置 * 某些请求不要拦截 * * @author xjwtt * @date 2018/8/21 */ @EnableWebMvc @Configuration public class WebConfig implements WebMvcConfigurer {/** * 加载的静态资源路径 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String templatesPath = System.getProperty("user.dir") + "/" + "templates/"; String staticPath = System.getProperty("user.dir") + "/" + "static/"; File templatesFile = new File(templatesPath); File staticFile = new File(staticPath); if (templatesFile.exists()) { registry.addResourceHandler("/**").addResourceLocations("file:" + templatesPath); } else { registry.addResourceHandler("/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/templates/"); }if (staticFile.exists()) { registry.addResourceHandler("/**").addResourceLocations("file:" + staticPath); } else { registry.addResourceHandler("/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/"); } registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); }/** * 跨域CORS设置 * * @param registry */ @Override //重写父类提供的跨域请求处理的接口 public void addCorsMappings(CorsRegistry registry) { //添加映射路径 registry.addMapping("/**") .allowedHeaders("*") //是否发送Cookie信息 .allowCredentials(true) //放行哪些原始域(请求方式) .allowedMethods("GET", "HEAD", "POST","PUT", "DELETE", "OPTIONS") //放行哪些原始域 .allowedOrigins("*") //放行哪些原始域(头部信息) .allowedHeaders("*"); } }

【前后端分离Springboot整合shiro|前后端分离Springboot整合shiro -- 01基础使用】转载于:https://my.oschina.net/u/3350266/blog/2209610

    推荐阅读