apache shiro jar包_springboot集成shiro

通过Shiro的认证与授权可以搭建一个有认证和权限体系的项目,用户需要登录之后才能访问应用服务。

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

1.集成导入jar包

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

官方提供了属性参数以及一些默认值。

5d911576496e42d8b4db39c095d80a9d

2.修改配置文件application.yml

shiro:    web:        enabled: trueloginUrl: /loginspring:      freemarker:           suffix: .ftl template-loader-path:       classpath: /templates/settings:        classic_compatible: true 

3.配置shiro的securityManager和自定义realm。

realm负责认证与授权,自定义realm由securityManager管理,所以这两个类需要重写。

然后还有一些资源的权限说明,所以一般需要定义ShiroFilterChainDefinition,常用的类有:

  • AuthorizingRealm
  • DefaultWebSecurityManager shiro的核心管理器
  • ShiroFilterChainDefinition 过滤器链配置
@Configurationpublic 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();               chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");              chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");               chainDefinition.addPathDefinition("/login", "anon");             chainDefinition.addPathDefinition("/doLogin", "anon");                 chainDefinition.addPathDefinition("/**", "authc");              return chainDefinition;     }}

ShiroFilterChainDefinition是定义过滤器配置的:

chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");

访问 /admin/**开头的链接,都需要已经完成登录认证 authc、并且拥有 admin角色权限才能访问。

说明文档:

bd4050f368dd4eac8947c011d7e35e05

可以看到每个简写单词都是一个过滤器的名称。比如authc代表着 FormAuthenticationFilter,常用的过滤器有:

  • authc 基于表单的拦截器,没有登录会跳到相应的登录页面登录
  • user 用户拦截器,用户已经身份验证 / 记住我登录的都可
  • anon 匿名拦截器,即不需要登录即可访问
  • roles 角色授权拦截器,验证用户是否拥有所有角色
  • perms 权限授权拦截器,验证用户是否拥有所有权限

继承超类 AuthorizingRealm

public abstract class AuthorizingRealm extends AuthenticatingRealm
1281c6a79cdf49dd8f9e6660a454423d

结合了授权与验证,还有缓存功能,我们自定义Realm的时候继承AuthorizingRealm即可。

  • com.markerhub.shiro.AccountRealm
public class AccountRealm extends AuthorizingRealm {    @Autowired    UserService userService;    /**     * 授权方法     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(        PrincipalCollection principalCollection) {        AccountProfile principal = (AccountProfile) principalCollection.getPrimaryPrincipal();        // 硬编码(赋予用户权限或角色)              if (principal.getUsername().equals("Test")) {            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()));        SecurityUtils.getSubject().getSession().setAttribute("profile", profile);        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(profile,                token.getCredentials(), getName());        return info;    }}
@Servicepublic class UserServiceImpl  implements UserService{    @Override    public AccountProfile login(String username, String password) {        //TODO 查库,然后匹配密码是否正确!        if (!"MarkerHub".equals(username)) {            // 抛出shiro异常,方便通知用户登录错误信息            throw new UnknownAccountException("用户不存在");        }        if (!"string".equals(password)) {            throw new IncorrectCredentialsException("密码错误");        }        AccountProfile profile = new AccountProfile();        profile.setId(1L);        profile.setUsername("Winson");        profile.setSign("Winson Sign");        return profile;    }}

5.增加控制器IndexController

@Controllerpublic 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";    }}@Controllerpublic 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";    }}@Controllerpublic 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";    }}@Controllerpublic 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";    }}

6.增加登录页面templates/login.ftl

    MarkerHub 登录

用户登录

欢迎关注公众号:MarkerHub

username: password:
${errorMess}

登录成功页面:

  • templates/index.ftl
    Title

登录成功:${profile.username}

${profile.sign}

退出

Done 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供关于Apache Shiro和Spring Boot集成的指导。以下是六个步骤: 1. 添加 Maven 依赖 您需要在 Maven 项目中添加以下依赖: ``` <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.7.1</version> </dependency> ``` 2. 配置 Shiro 您需要在应用程序的 `application.properties` 文件中设置 Shiro 的属性。以下是一个示例: ``` # Shiro Configuration shiro.loginUrl = /login shiro.successUrl = /home shiro.unauthorizedUrl = /unauthorized shiro.filterChainDefinitionMap = /login=anon\n/home=authc\n/logout=logout shiro.rememberMe.cookie.name = rememberMe shiro.rememberMe.cookie.maxAge = 2592000 shiro.rememberMe.cipherKey = 3AvVhmFLUs0KTA3Kprsdag== ``` 这里我们设置了登录页面,成功页面,未授权页面,过滤器链定义和记住我 cookie。 3. 创建 ShiroRealm 您需要创建一个继承 `AuthorizingRealm` 的类来实现自己的 Realm。以下是一个示例: ``` @Component public class ShiroRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); User user = (User) principals.getPrimaryPrincipal(); authorizationInfo.addRole(user.getRole()); authorizationInfo.setStringPermissions(user.getPermissions()); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String email = usernamePasswordToken.getUsername(); User user = userService.findByEmail(email); if (user == null) { throw new UnknownAccountException(); } return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); } } ``` 这里我们实现了 `doGetAuthorizationInfo()` 和 `doGetAuthenticationInfo()` 方法来实现授权和认证。 4. 配置 ShiroFilter 您需要在应用程序中创建一个 `ShiroFilter` 类来配置 Shiro 过滤器。以下是一个示例: ``` @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/images/**", "anon"); filterChainDefinitionMap.put("/fonts/**", "anon"); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setSuccessUrl("/home"); shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); securityManager.setRememberMeManager(rememberMeManager()); return securityManager; } @Bean public ShiroRealm shiroRealm() { return new ShiroRealm(); } @Bean public RememberMeManager rememberMeManager() { CookieRememberMeManager rememberMeManager = new CookieRememberMeManager(); rememberMeManager.setCookie(rememberMeCookie()); rememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag==")); return rememberMeManager; } @Bean public SimpleCookie rememberMeCookie() { SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setMaxAge(2592000); return simpleCookie; } } ``` 这里我们创建了一个 `ShiroFilterFactoryBean` 和一个 `SecurityManager`。我们还设置了过滤器链和记住我 cookie。 5. 创建登录页面 您需要创建一个登录页面来允许用户输入他们的凭证。以下是一个示例: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <h1>Login</h1> <form method="post" action="/login"> <label>Email:</label> <input type="email" name="email"> <br> <label>Password:</label> <input type="password" name="password"> <br> <input type="submit" value="Login"> </form> </body> </html> ``` 6. 创建授权页面 您需要创建一个授权页面来显示用户是否已被授权。以下是一个示例: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Welcome!</h1> <p>You have been successfully authenticated and authorized.</p> </body> </html> ``` 以上是关于Apache Shiro和Spring Boot集成的六个步骤。希望这可以帮助你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值