栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

只需要6个步骤,springboot集成shiro,并完成登录

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

只需要6个步骤,springboot集成shiro,并完成登录

小Hub领读:

导入jar包,配置yml参数,编写ShiroConfig定义DefaultWebSecurityManager,重写Realm,编写controller,编写页面,一气呵成。搞定,是个高手~


上面一篇文章中,我们已经知道了shiro的认证与授权过程,这也是shiro里面最核心常用的基础功能。现在我们把shiro集成到我们的项目中,开始搭建一个有认证和权限体系的项目,比如用户中心需要登录之后才能访问等!

集成Shiro

根据官方文档:
https://shiro.apache.org/spring-boot.html

**第一步:**集成导入jar包:


    org.apache.shiro
    shiro-spring-boot-web-starter
    1.4.2

有些同学还在用shiro-spring的jar包,但是集成的配置就相对多一点,所以可以直接使用starter包更加方便。

**第二步:**写好配置,官方给我们提供的属性参数,以及一些默认值,如果不符合我们的需求,可以自行改动哈。

从配置上就可以看出,shiro的注解功能,rememberMe等功能已近自动集成进来了。所以starter包使用起来还是非常简单的,只需要熟悉shiro的流程,从0开发不在话下哈。

  • application.yml
shiro:
  web:
    enabled: true
  loginUrl: /login
spring:
  freemarker:
    suffix: .ftl # 注意新版本后缀是 .ftlh
    template-loader-path: classpath:/templates/
    settings:
      classic_compatible: true #处理空值

上面的配置,我就改了一下登录的url,其他都是使用默认的,作为我们最简单的测试,相信你们。

**第三步:**配置shiro的securityManager和自定义realm。因为realm负责我们的认证与授权,所以是必须的,自定义的realm必须要交给securityManager管理,所以这两个类需要重写。然后还有一些资源的权限说明,所以一般需要定义ShiroFilterChainDefinition,所以有3个类我们常写的:

  • AuthorizingRealm
  • DefaultWebSecurityManager shiro的核心管理器
  • ShiroFilterChainDefinition 过滤器链配置
@Configuration
public class ShiroConfig {

    @Bean
    AccountRealm accountRealm() {
 return new AccountRealm();
    }

    @Bean
    public DefaultWebSecurityManager securityManager(AccountRealm accountRealm) {
 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
 securityManager.setRealm(accountRealm);
 return securityManager;
    }

    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
 DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

 // logged in users with the 'admin' role
 chainDefinition.addPathDefinition("/admin
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

 AccountProfile principal = (AccountProfile) principalCollection.getPrimaryPrincipal();

 // 硬编码(赋予用户权限或角色)
 if(principal.getUsername().equals("MarkerHub")){
     SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
     info.addRole("admin");
     return info;
 }

 return null;
    }

    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
 AccountProfile profile = userService.login(token.getUsername(), String.valueOf(token.getPassword()));
 // 把用户信息存到session中,方便前端展示
 SecurityUtils.getSubject().getSession().setAttribute("profile", profile);

 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(profile, token.getCredentials(), getName());
 return info;
    }
}
  • com.markerhub.service.impl.UserServiceImpl
@Service
public class UserServiceImpl implements UserService {

    @Override
    public AccountProfile login(String username, String password) {

 //TODO 查库,然后匹配密码是否正确!

 if(!"MarkerHub".equals(username)) {
     // 抛出shiro异常,方便通知用户登录错误信息
     throw new UnknownAccountException("用户不存在");
 }
 if(!"111111".equals(password)) {
     throw new IncorrectCredentialsException("密码错误");
 }

 AccountProfile profile = new AccountProfile();
 profile.setId(1L);
 profile.setUsername("MarkerHub");
 profile.setSign("欢迎关注公众号MarkerHub哈");

 return profile;
    }
}

上面代码中,我login方法直接给出了账号MarkerHub,并赋予了角色admin。

**第五步:**ok,准备动作已经热身完毕,接下来我们去编写登录、退出接口,以及我们的界面:

  • com.markerhub.controller.IndexController
@Controller
public class IndexController {

    @Autowired
    HttpServletRequest req;

    @RequestMapping({"/", "/index"})
    public String index() {
 System.out.println("已登录,正在访问!!");
 return "index";
    }

    @GetMapping("/login")
    public String login() {
 return "login";
    }

    
    @PostMapping("/doLogin")
    public String doLogin(String username, String password) {

 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
 try {
     SecurityUtils.getSubject().login(token);

 } catch (AuthenticationException e) {
     if (e instanceof UnknownAccountException) {
  req.setAttribute("errorMess", "用户不存在");
     } else if (e instanceof LockedAccountException) {
  req.setAttribute("errorMess", "用户被禁用");
     } else if (e instanceof IncorrectCredentialsException) {
  req.setAttribute("errorMess", "密码错误");
     } else {
  req.setAttribute("errorMess", "用户认证失败");
     }
     return "/login";
 }
 return "redirect:/";
    }


    
    @GetMapping("/logout")
    public String logout() {
 SecurityUtils.getSubject().logout();
 return "redirect:/login";
    }

}

**第六步:**登录页面:

  • templates/login.ftl



    
    MarkerHub 登录


    用户登录
    欢迎关注公众号:MarkerHub

    

    ${errorMess}


登录成功页面:

  • templates/index.ftl
登录成功:${profile.username}
${profile.sign}

退出

ok,代码我们已经编写完成,接下来,我们运行项目,然后访问首页,将自行跳转到登录页面,然后输入账号密码之后,我们可以看到完成登录!

登录界面:

登录成功页面:

结束语

好了,今天做了一个极简的登录注册功能,介绍了一下shiro的基本整合步骤。流程还是挺简单的哈哈,不知道你看懂了没。

而在一些负载均衡的场景中,我们的会话信息是需要共享的,所以shiro一般会和redis整合在一起,你知道怎么整合吗?我们明天再聊哈,记得来哦,MarkerHub每天发文时间19点20分。

附:demo git源码地址:https://github.com/MarkerHub/JavaDemo/tree/master/整合示例/springboot-shiro-demo

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号