实现对特定角色和特定路径拦截

This commit is contained in:
fjy8018@qq.com
2018-07-06 15:44:45 +08:00
parent 14bdaf5989
commit 0be0ccf113
11 changed files with 226 additions and 173 deletions

View File

@@ -10,7 +10,7 @@ import org.springframework.context.annotation.ComponentScan;
@MapperScan(basePackages = {"top.fjy8018.shiro.mapper"})
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class, args);
}
}

View File

@@ -15,6 +15,7 @@ import java.util.LinkedHashMap;
/**
* shiro核心配置
*
* @author F嘉阳
* @date 2018/7/6 10:29
*/
@@ -22,7 +23,7 @@ import java.util.LinkedHashMap;
public class ShiroConfiguration {
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager){
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(manager);
@@ -32,11 +33,18 @@ public class ShiroConfiguration {
bean.setUnauthorizedUrl("/unauthorized");
// 配置拦截
LinkedHashMap<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 主页设置拦截第二个参数的含义在org.apache.shiro.web.filter.mgt.DefaultFilter的枚举类中authc为表单验证
filterChainDefinitionMap.put("/index","authc");
filterChainDefinitionMap.put("/index", "authc");
// 登录页无需拦截anon即匿名访问
filterChainDefinitionMap.put("/login","anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/doLogin","anon");
// 指定页面只能给指定用户访问校验角色名称类org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
filterChainDefinitionMap.put("/admin","roles[admin]");
// 用户登录后可以访问所有接口
filterChainDefinitionMap.put("/**", "user");
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
@@ -45,7 +53,7 @@ public class ShiroConfiguration {
@Bean("securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm){
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(authRealm);
return manager;
@@ -54,11 +62,12 @@ public class ShiroConfiguration {
/**
* 自定义的Realm
*
* @param matcher
* @return
*/
@Bean("authRealm")
public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher){
public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(matcher);
return authRealm;
@@ -66,20 +75,22 @@ public class ShiroConfiguration {
/**
* 自定义密码校验规则
*
* @return
*/
@Bean("credentialsMatcher")
public CredentialsMatcher credentialsMatcher(){
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
/**
* 配置spring与shiro关联指定spring使用的SecurityManager为自定义的SecurityManager
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
@@ -88,10 +99,11 @@ public class ShiroConfiguration {
/**
* 代理所有servlet的过滤器链
*
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);

View File

@@ -19,25 +19,34 @@ import javax.servlet.http.HttpSession;
public class LoginController {
@RequestMapping("/login")
public String login(){
public String login() {
return "login";
}
@RequestMapping("/doLogin")
public String doLogin(LoginForm form, HttpSession session){
UsernamePasswordToken token = new UsernamePasswordToken(form.getUsername(),form.getPassword());
public String doLogin(LoginForm form, HttpSession session) {
UsernamePasswordToken token = new UsernamePasswordToken(form.getUsername(), form.getPassword());
Subject subject = SecurityUtils.getSubject();
try{
try {
subject.login(token);
// 若未发生异常则此处获得用户
User user = (User) subject.getPrincipal();
// 将用户写入session
session.setAttribute(GlobalConstant.USER_SESSION_KEY,user);
session.setAttribute(GlobalConstant.USER_SESSION_KEY, user);
return "index";
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
return "login";
}
}
@RequestMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
if (subject != null) {
subject.logout();
}
return "login";
}
}

View File

@@ -2,9 +2,11 @@ package top.fjy8018.shiro.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 页面导航
*
* @author F嘉阳
* @date 2018/7/6 10:57
*/
@@ -12,7 +14,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class NavController {
@RequestMapping("/index")
public String index(){
public String index() {
return "index";
}
@RequestMapping("/admin")
@ResponseBody
public String admin() {
return "admin success";
}
}

View File

@@ -7,6 +7,7 @@ import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
/**
* 自定义校验规则
*
* @author F嘉阳
* @date 2018/7/6 10:25
*/
@@ -15,9 +16,9 @@ public class CredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String password = new String (usernamePasswordToken.getPassword());
String password = new String(usernamePasswordToken.getPassword());
String dbPassword = (String) info.getCredentials();
// 数据库密码与用户密码匹配
return this.equals(password,dbPassword);
return this.equals(password, dbPassword);
}
}

View File

@@ -4,6 +4,7 @@ import lombok.Data;
/**
* 登录表单
*
* @author F嘉阳
* @date 2018/7/6 10:59
*/

View File

@@ -27,6 +27,7 @@ public class AuthRealm extends AuthorizingRealm {
/**
* shiro登录成功后的授权方法
*
* @param principalCollection
* @return
*/
@@ -36,14 +37,16 @@ public class AuthRealm extends AuthorizingRealm {
User user = (User) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
List<String> permissionList = new ArrayList<>();
List<String> roleList = new ArrayList<>();
Set<Role> roleSet = user.getRoles();
// 取角色
if (CollectionUtils.isNotEmpty(roleSet)){
for (Role role : roleSet){
if (CollectionUtils.isNotEmpty(roleSet)) {
for (Role role : roleSet) {
roleList.add(role.getRname());
// 取权限
Set<Permission> permissionSet = role.getPermissions();
if (CollectionUtils.isNotEmpty(permissionSet)){
for (Permission permission : permissionSet){
if (CollectionUtils.isNotEmpty(permissionSet)) {
for (Permission permission : permissionSet) {
permissionList.add(permission.getName());
}
}
@@ -52,12 +55,14 @@ public class AuthRealm extends AuthorizingRealm {
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissionList);
info.addRoles(roleList);
return info;
}
/**
* 认证登录
*
* @param authenticationToken
* @return
* @throws AuthenticationException
@@ -69,6 +74,6 @@ public class AuthRealm extends AuthorizingRealm {
String username = usernamePasswordToken.getUsername();
// 通过用户名查用户是否存在,合法则登录认证通过
User user = userService.findByUsername(username);
return new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
}

View File

@@ -2,28 +2,28 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.fjy8018.shiro.mapper.UserMapper">
<resultMap id="userMap" type="top.fjy8018.shiro.dataobject.User" >
<resultMap id="userMap" type="top.fjy8018.shiro.dataobject.User">
<id property="uid" column="uid"/>
<result property="username" column="username" />
<result property="password" column="password" />
<result property="username" column="username"/>
<result property="password" column="password"/>
<collection property="roles" ofType="top.fjy8018.shiro.dataobject.Role">
<id property="rid" column="rid" />
<result property="rname" column="rname" />
<id property="rid" column="rid"/>
<result property="rname" column="rname"/>
<collection property="permissions" ofType="top.fjy8018.shiro.dataobject.Permission">
<id property="pid" column="pid" />
<result property="name" column="name" />
<result property="url" column="url" />
<id property="pid" column="pid"/>
<result property="name" column="name"/>
<result property="url" column="url"/>
</collection>
</collection>
</resultMap>
<select id="findByUsername" parameterType="java.lang.String" resultMap="userMap">
SELECT u.*,r.*,p.*
FROM user u
INNER JOIN user_role ur ON ur.uid = u.uid
INNER JOIN role r ON ur.uid = r.rid
INNER JOIN permission_role pr ON r.rid = pr.rid
INNER JOIN permission p ON pr.pid = p.pid
WHERE u.username = #{username}
FROM user u
INNER JOIN user_role ur ON ur.uid = u.uid
INNER JOIN role r ON ur.uid = r.rid
INNER JOIN permission_role pr ON r.rid = pr.rid
INNER JOIN permission p ON pr.pid = p.pid
WHERE u.username = #{username}
</select>
</mapper>