java spring 权限_Java权限管理

1f37ef22549dbf8c639b35ab9019dd43.png

一、权限框架介绍

1. 权限管理

本质:用户身份认证+授权

流程:用户首先经过身份认证,通过后即可访问该资源

1.1 用户身份认证

  b6472589d189084c007bf3d1be596782.png

1.2 授权流程

cb67f0c186a3c921cabdb50ce61fd6e1.png

2. 权限框架

Shiro和Spring Security比较

(1)Shiro比Spring更容易使用,实现和理解

(2)Spring Security有更好的社区支持

(3)Apache Shiro在Spring Security处理密码学方面有一个额外的模块

(4)Spring-security 对spring 结合较好,如果项目用的springmvc ,使用起来很方便。但是如果项目中没有用到spring,那就不要考虑它了。

(5)Shiro 功能强大、且 简单、灵活。是Apache 下的项目比较可靠,且不跟任何的框架或者容器绑定,可以独立运行

二、Shiro基础介绍

1. Shiro三个核心组件

1.1 Subject(当前操作用户)

不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

1.2 SecurityManager(维护中心)

Shiro框架的核心,典型的Facade模式,用来协调内部组件实例,并提供安全管理的各种服务。

1.3 Realm(数据中心)

对用户认证(登录)和授权(访问控制)时,Shiro会从配置的Realm中查找用户及其权限信息。

当配置Shiro时,至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

2. Shiro相关类介绍

(1)Authentication 认证 ---- 用户登录

(2)Authorization 授权 --- 用户具有哪些权限

(3)Cryptography 安全数据加密

(4)Session Management 会话管理

(5)Web Integration web系统集成

(6)Interations 集成其它应用,spring、缓存框架

3. Shiro 特点

(1)易于理解的 Java Security API;

(2)简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);

(3)对角色的简单的签权(访问控制),支持细粒度的签权;

(4)支持一级缓存,以提升应用程序的性能;

(5)内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;

(6)异构客户端会话访问;

(7)非常简单的加密 API;

(8)不跟任何的框架或者容器捆绑,可以独立运行

三、Spring Boot整合Shiro代码实战

3.1 pom.xml中添加依赖

com.h2database

h2

runtime

org.apache.shiro

shiro-spring

1.3.2

3.2 编写测试Controller类@RequiresPermissions("user:list")

@RequiresRoles("admin")

@ResponseBody

@RequestMapping("/hello")

public String hello(){

System.out.println(person);

return "hello world";

}

@RequestMapping(value = "/login", method = RequestMethod.GET)

@ResponseBody

public String defaultLogin() {

return "首页";

}

@RequestMapping(value = "/login", method = RequestMethod.POST)

@ResponseBody

public String login(@RequestParam("username") String username, @RequestParam("password") String password) {

// 从SecurityUtils里边创建一个 subject Subject subject = SecurityUtils.getSubject();

// 在认证提交前准备 token(令牌)

UsernamePasswordToken token = new UsernamePasswordToken(username, password);

// 执行认证登陆

try {

subject.login(token);

} catch (UnknownAccountException uae) {

return "未知账户";

} catch (IncorrectCredentialsException ice) {

return "密码不正确";

} catch (LockedAccountException lae) {

return "账户已锁定";

} catch (ExcessiveAttemptsException eae) {

return "用户名或密码错误次数过多";

} catch (AuthenticationException ae) {

return "用户名或密码不正确!";

}

if (subject.isAuthenticated()) {

return "登录成功";

} else {

token.clear();

return "登录失败";

}

}

3.3 配置类@Bean(name = "shiroFilter")

public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setSecurityManager(securityManager);

//添加Shiro内置过滤器

/**

* Shiro内置过滤器,可以实现权限相关的拦截器

* 常用的过滤器:

* anon: 无需认证(登录)可以访问

* authc: 必须认证才可以访问

* user: 如果使用rememberMe的功能可以直接访问

* perms: 该资源必须得到资源权限才可以访问

* role: 该资源必须得到角色权限才可以访问

*/

shiroFilterFactoryBean.setLoginUrl("/login");//登录页

shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");

Map filterChainDefinitionMap = new LinkedHashMap<>();

//

filterChainDefinitionMap.put("/webjars/**", "anon");

filterChainDefinitionMap.put("/login", "anon");

filterChainDefinitionMap.put("/", "anon");

filterChainDefinitionMap.put("/front/**", "anon");

filterChainDefinitionMap.put("/api/**", "anon");

filterChainDefinitionMap.put("/admin/**", "authc");

filterChainDefinitionMap.put("/user/**", "authc");

filterChainDefinitionMap.put("/hello/**","perms[user:add]");

//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证

filterChainDefinitionMap.put("/**", "authc");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

return shiroFilterFactoryBean;

}

@Bean

public DefaultWebSecurityManager securityManager() {

DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();

defaultSecurityManager.setRealm(customRealm());

DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();

DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();

defaultSessionStorageEvaluator.setSessionStorageEnabled(false);

subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);

defaultSecurityManager.setSubjectDAO(subjectDAO);

return defaultSecurityManager;

}

@Bean

@DependsOn("lifecycleBeanPostProcessor")

public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {

DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();

defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);

return defaultAdvisorAutoProxyCreator;

}

@Bean

public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {

return new LifecycleBeanPostProcessor();

}

@Bean

public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {

AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();

authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());

return authorizationAttributeSourceAdvisor;

}

@Bean

public CustomRealm customRealm() {

CustomRealm customRealm = new CustomRealm();

return customRealm;

}

3.4 Realm/**

* 权限认证,即登录过后,每个身份不一定,对应的所能看的页面也不一样。

* @param principalCollection

* @return

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

User user = null;

String username = "";

if (Objects.nonNull(principalCollection)){

user = (User)principalCollection.getPrimaryPrincipal();

}

username = (String) SecurityUtils.getSubject().getPrincipal();

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//用户角色

Set roleSets = new HashSet<>();

roleSets.add("admin");

roleSets.add("test");

info.setRoles(roleSets);

//角色对应的权限

Set permissionSet = new HashSet<>();

permissionSet.add("user:show");

permissionSet.add("user:admin");

info.addStringPermissions(permissionSet);

return info;

}

/**

* 身份认证。即登录通过账号和密码验证登陆人的身份信息。

* @param authenticationToken

* @return

* @throws AuthenticationException

*/@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("-------身份认证方法--------");

//authenticationToken.getCredentials()----token?如何来?

String token = (String) authenticationToken.getCredentials();

if (StringUtils.isEmpty(token)){

HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();

Map parameterMap = request.getParameterMap();

Set> entrys = parameterMap.entrySet();

for (Map.Entry entry:entrys) {

System.out.println(entry.getKey()+"============"+entry.getValue());

}

throw new AuthenticationException("token为空");

}

User user = this.checkAuthenticationToken(token);

//String userName = (String) authenticationToken.getPrincipal();

//String userPwd = new String((char[]) authenticationToken.getCredentials()); return new SimpleAuthenticationInfo(user, token,getName());

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值