Java岗大厂面试百日冲刺Day43— Shrio1 (日积月累,每日三题)

Posted _陈哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java岗大厂面试百日冲刺Day43— Shrio1 (日积月累,每日三题)相关的知识,希望对你有一定的参考价值。

  大家好,我是陈哈哈,北漂五年。相信大家和我一样,都有一个大厂梦,作为一名资深Java选手,深知面试重要性,接下来我准备用100天时间,基于Java岗面试中的高频面试题,以每日3题的形式,带你过一遍热门面试题及恰如其分的解答。

  一路走来,随着问题加深,发现不会的也愈来愈多。但底气着实足了不少,相信不少朋友和我一样,日积月累才是最有效的学习方式!想起高三时一个同学的座右铭:只有沉下去,才能浮上来。共勉(juan)。



  本栏目Java开发岗高频面试题主要出自以下各技术栈:Java基础知识集合容器并发编程JVMSpring全家桶MyBatis等ORMapping框架mysql数据库Redis缓存RabbitMQ消息队列Linux操作技巧等。

  相信很多朋友简历中都写了熟练使用Shrio框架,这也是我们做单点登录经常会用到的途径之一。既然写上了,就要做好被问到的准备,一般会问哪些呢?其实,除了你使用过程中出现的一些实际操作遇到的BUG以外,以下问题我劝你都了解一下,这是用好Shrio的同学都应该了解的内容,淦(juan)!

面试题1:你来简单介绍一下Shiro框架吧?

  Apache Shiro是Java的一个安全框架。使用Shiro可以非常容易的开发出足够好的应用。其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成功能:认证、授权、加密、会话管理、与Web集成、缓存等功能。

Shiro包括三个核心组件:Subject,SecurityManager和Realm。

  • Subject:即当前操作用户。Subject在shiro中是一个接口,定义了很多认证授权的方法,外部程序通过Subject进行认证授权,而Subject通过SecurityManager进行认证授权。其实SecurityManager才是实际的执行者。

  • SecurityManager安全管理器所有与安全有关的操作都会与SecurityManager交互,且管理着所有的Subject,是shiro的核心,负责与shiro其他组件进行交互,如通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。SecurityManager也是一个接口,继承了Authenticator,Authorizer,SessionManager三个接口

  • Realm:Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。Shiro从Realm获取安全数据(如用户,角色,权限);也就是说SecurityManager要验证用户身份或操作权限,需要从Realm获取相应数据来判断(用户是否能登录,是否拥有什么权限等)。

追问1:Shiro常见的权限控制方式有哪几种?

● 方法注解权限控制

● 页面标签权限控制

● 代码级别权限控制

● URL级别权限控制

1. 方法注解权限控制:

  基于代理技术实现,首先要在spring配置文件中进行声明开启shiro注解,然后在代码方法上用注解声明调用该方法需要什么权限。

<!-- 开启shiro框架注解支持 -->
<bean id="defaultAdvisorAutoProxyCreator" 
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<!-- 必须使用cglib方式为Action对象创建代理对象 -->
<property name="proxyTargetClass" value="true"/>
</bean>

<!-- 配置shiro框架提供的切面类,用于创建代理对象 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

然后在方法上声明:

@RequiresPermissions("user-delete")
//执行这个方法,需要当前用户具有user-delete这个权限
public String deleteUser(){
	staffService.deleteUser(user_name);
	return LIST;
}

2. 页面标签权限控制:

  首先要在jsp页面进入表签:

<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
然后包裹权限控制的内容
<shiro:hasPermission name="user-delete">
	<!— 有权限 >  
	<button>删除用户</button>
</shiro:hasPermission>

3.代码级别权限控制:

public String deleteUser(Model model){

	Subject subject = SecurityUtils.getSubject();  
	if(subject..checkPermission("user-delete")) {  
		//有权限  
	} else {  
		//无权限  
	}
}

4. URL拦截权限控制:

  基于filter过滤器实现,我们在spring配置文件中配置shiroFilter时配置

<!--指定URL级别拦截策略  -->
<property name="filterChainDefinitions"> 
	<value>
		/css/ = anon
		/js/ = anon
		/images/ = anon
		/validatecode.jsp = anon
		/login.jsp = anon
		/user/userlogin = anon
		/user/deleteUser = perms["user-delete"]
		/** = authc
	</value>
</property>

正常情况下,没有授权会跳转到为授权(登录)页面

anon:表示不拦截(匿名用户可访问)
user:使用rememberme的用户可访问
perms:对应权限可访问
role:对应的角色才能访问
authc:认证用户可访问

  使用shiro进行权限控制时 这四种方法并不是进行单一的使用,是相互结合的使用从而完整的进行权限控制。

追问2:你还知道Shiro的其他组件么?简单说一下

  • Subject: 与应用交互的用户
  • SecurityManager: 相当于SpringMVC中的DispatcherServlet,所有具体的交互都由SecurityManager控制;它管理着所有的Subject,且负责进行认证,授权,会话和缓存的管理
  • Realm: 安全实体数据源,可以有1个或多个

除了以上三个核心组件外,还包括:

  • Authenticator: 认证器, 对用户身份进行验证;Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,也可以自定义
  • Authorizer: 授权器,决定用户是否有权限进行某种操作,控制着用户能访问应用中的哪些功能
  • SessionManager: 管理session的生命周期(可以实现单点登录)
  • CacheManager: 缓存管理器
  • Cryptography: 密码管理模块

课间休息,又来秀一下来自咱们群里同学的搬砖工地,坐标:济南 大明湖

作者:帅玉阳


面试题2:说一下Shiro认证和授权过程

认证流程

  • 首先调用 Subject.login(token)进行登录,其会自动委托给 Security Manager,调用之前必须通过 SecurityUtils.setSecurityManager()设置;
  • SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份验证;
  • Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现;
  • Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm 身份验证;
  • Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回 / 抛出异常表示身份验证失败了。此处可以配置多个 Realm,将按照相应的顺序及策略进行访问。

shiro中有三种认证策略的具体实现:

  • AtleastOneSuccessfulStrategy: 只要有一个realm验证成功,则成功
  • FirstSuccessfulStrategy: 第一个realm验证成功,则成功,后续realm将被忽略
  • AllSuccessfulStrategy: 所有realm成功,验证才成功

授权流程

  shiro判断用户是否有权限首先会从realm中获取用户所拥有的权限角色信息,然后再匹配当前的角色或权限是否包含,从而判定用户是否有权限。

  • 首先调用 Subject.isPermitted/hasRole接口,其会委托给 SecurityManager,而 SecurityManager 接着会委托给 Authorizer
  • Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过 PermissionResolver 把字符串转换成相应的 Permission 实例;
  • 在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;
  • Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会委托给 ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted/hasRole 会返回 true,否则返回 false 表示授权失败。继承 AuthorizingRealm而不是实现 Realm 接口;


课间休息,又来秀一下来自咱们群里同学的搬砖工地。

作者:FEI


面试题3:Shiro中常见的异常有哪些?

异常原因
UnknownAccountException帐号不存在
IncorrectCredentialsException密码错误
DisabledAccountException帐号被禁用
LockedAccountException帐号被锁定
ExcessiveAttemptsException登录失败次数过多
ExpiredCredentialsException凭证过期

每日小结

  今天我们复习了面试中常考的Shiro框架相关的三个问题,你做到心中有数了么?对了,如果你的朋友也在准备面试,请将这个系列扔给他,如果他认真对待,肯定会感谢你的!!好了,今天就到这里,学废了的同学,记得在评论区留言:打卡。,给同学们以激励。

以上是关于Java岗大厂面试百日冲刺Day43— Shrio1 (日积月累,每日三题)的主要内容,如果未能解决你的问题,请参考以下文章

Java岗大厂面试百日冲刺 - 日积月累,每日三题Day03——Java高级篇

Java岗大厂面试百日冲刺 - 日积月累,每日三题Day02——Java高级篇

Java岗大厂面试百日冲刺Day47— 并发编程4(日积月累,每日三题)

Java岗大厂面试百日冲刺 - 日积月累,每日三题Day22—— 并发编程2

Java岗大厂面试百日冲刺 - 日积月累,每日三题Day21—— Linux命令

Java岗大厂面试百日冲刺 - 日积月累,每日三题Day51—— tomcat