}
第二步:在项目启动类中添加Realm对象配置,关键代码如下:,关键代码如下:
@Bean
public Realm realm() {//org.apache.shiro.realm.Realm
return new ShiroRealm();
}
第三步: 在启动类中定义过滤规则(哪些访问路径要进行认证才可以访问),关键代码如下:
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
//配置/user/login/**开头的资源,可以匿名访问(不用登录就可以访问),
//其中anon为shiro框架指定的匿名过滤器 chainDefinition.addPathDefinition(“/user/login/**”,“anon”);
//配置登出操作
chainDefinition.addPathDefinition(“/user/logout”,“logout”);
//配置以/**开头的资源必须都要经过认证,
//其中authc为shiro框架指定的认证过滤器
chainDefinition.addPathDefinition(“/**”, “authc”);
return chainDefinition;
}
第四步:在spring的配置文件(application.yml)中,添加登录页面的配置,关键代码如下:
shiro:
loginUrl: /login.html
说明:假如没有login.html,需要先准备login.html
打开浏览器,输入http://localhost/user/检测是否会出现登录窗口。
=======================================================================
身份认证即判定用户是否是系统的合法用户,用户访问系统资源时的认证(对用户身份信息的认证)流程图所示:
其中认证流程分析如下:
-
系统调用subject的login方法将用户信息提交给SecurityManager
-
SecurityManager将认证操作委托给认证器对象Authenticator
-
Authenticator将用户输入的身份信息传递给Realm。
-
Realm访问数据库获取用户信息然后对信息进行封装并返回。
-
Authenticator 对realm返回的信息进行身份认证。
思考:不使用shiro框架如何完成认证操作?filter,intercetor。
第一步: 定义Realm类,并修改ShiroRealm中获取认证信息的方法,关键代码如下:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
//1.获取用户提交的认证用户信息
UsernamePasswordToken upToken=(UsernamePasswordToken) authenticationToken;
String username=upToken.getUsername();
//2.基于用户名查询从数据库用户信息
//3.判断用户是否存在
if(!“jack”.equals(username)) throw new UnknownAccountException();//账户不存在
//5.封装认证信息并返回
String salt=“ABCD”;
ByteSource credentialsSalt= ByteSource.Util.bytes(salt);
String hashedPassword=“来自数据库的密码”;
SimpleAuthenticationInfo info=
new SimpleAuthenticationInfo(
username, //principal 传入的用户身份
hashedPassword,//hashedCredentials
credentialsSalt,//credentialsSalt
getName());
return info;
}
第二步:在ShiroRealm中重谢获取凭证加密算法的方法,关键代码如下:
@Override
public CredentialsMatcher getCredentialsMatcher() {
HashedCredentialsMatcher matcher=new HashedCredentialsMatcher();
matcher.setHashAlgorithmName(“MD5”);
matcher.setHashIterations(1);
return matcher;
}
第三步:定义Controller逻辑
@GetMapping(“/login/{username}/{password}”)
public JsonResult doLogin(@PathVariable String username,
@PathVariable String password){
//将账号和密码封装token对象
UsernamePasswordToken token = //参考官网
new UsernamePasswordToken(username, password);
//基于subject对象将token提交给securityManager
Subject subject = SecurityUtils.getSubject();
subject.login(token);//提交给securityManager
return new JsonResult(“login ok”);
}
第四步::统一异常处理类中添加shiro异常处理代码,关键如下:
@ExceptionHandler(ShiroException.class)
public JsonResult doShiroException(ShiroException e){
JsonResult r=new JsonResult();
r.setState(0);
if(e instanceof UnknownAccountException){
r.setMessage(“用户名不存在”);
}else if(e instanceof IncorrectCredentialsException){
r.setMessage(“密码不正确”);
}else if(e instanceof LockedAccountException){
r.setMessage(“账户被锁定”);
}else if(e instanceof AuthorizationException){
r.setMessage(“没有权限”);
}else{
r.setMessage(“认证或授权失败”);
}
return r;
}
假如已配置,则可忽略。
第一步:在过滤配置中允许登录时的url匿名访问,关键代码如下:
chainDefinition.addPathDefinition(“/user/login/**”,“anon”);
第二步:再过滤配置中配置登出url操作,关键代码如下:
chainDefinition.addPathDefinition(“/user/logout”,“logout”);
第三步:启动服务器,进行登录、登出访问测试
======================================================================
授权即对用户资源访问的授权(是否允许用户访问此资源),用户访问系统资源时的授权流程如图所示:
其中授权流程分析如下:
-
系统调用subject相关方法将用户信息(例如isPermitted)递交给SecurityManager。
-
SecurityManager将权限检测操作委托给Authorizer对象。
-
Authorizer将用户信息委托给realm。
-
Realm访问数据库获取用户权限信息并封装。
-
Authorizer对用户授权信息进行判定。
思考:思考不使用shiro如何完成授权操作?intercetor,aop。
4.2 授权逻辑实现
4.2.1 Realm逻辑
修改ShiroRealm中获取权限并封装权限信息的方法,关键代码如下:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principalCollection) {
//1.获取登录用户(登录时传入的用户身份是谁)
//2.基于登录用户id获取用户权限标识(后续从数据库获取)
Set stringPermissions=new HashSet<>();
Set stringPermissions=new HashSet<>();
stringPermissions.add(“sys:user:retrieve”)
stringPermissions.add(“sys:user:create”)
//3.封装数据并返回
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.setStringPermissions(stringPermissions);
return info;
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
友,同时减轻大家的负担。**
[外链图片转存中…(img-p0eISavZ-1714698585721)]
[外链图片转存中…(img-yZOO4fUC-1714698585721)]
[外链图片转存中…(img-LoNBcC6S-1714698585722)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!