Estrutura shiro integrada do Springboot

Visão geral do shiro

  1. Apache Shiro é uma estrutura de segurança para Java
  2. O Shiro é uma estrutura de segurança Java poderosa e fácil de usar, usada principalmente para autenticação, autorização, criptografia, gerenciamento de sessões mais convenientes, integração com a Web, cache, etc.
  3. Shiro é pequeno e simples de usar
  4. Há segurança na primavera, que é uma estrutura de permissões, que depende muito da primavera e não é fácil de usar sem o shiro.
  5. O shiro não depende da primavera, o shiro não pode apenas implementar o gerenciamento de permissões para aplicativos da web, mas também implementar o sistema c / s, gerenciamento distribuído de permissões do sistema,
  6. Shiro é uma estrutura leve, e mais e mais projetos corporativos estão usando Shiro.

Conceitos principais do Shiro

Insira a descrição da imagem aqui

  1. Autenticação: autenticação de autenticação / login para verificar se o usuário tem a identidade correspondente;
  2. Autorização: autorização, ou seja, verificação de autorização, para verificar se um usuário autenticado possui uma certa autorização;
  3. Gerenciador de sessões: gerenciamento de sessões, ou seja, uma sessão após o usuário efetuar login. Antes de efetuar logout, todas as informações estão na sessão;
  4. Criptografia: criptografia para proteger a segurança dos dados
  5. Suporte da Web: O suporte da Web pode ser facilmente integrado ao ambiente da Web;
  6. Armazenamento em cache: em cache, por exemplo, depois que um usuário faz login, suas informações e funções / permissões de usuário não precisam ser verificadas todas as vezes, o que pode melhorar a eficiência;
  7. Simultaneidade: o Shiro suporta a verificação simultânea de aplicativos multithread, ou seja, se outro thread for iniciado em um thread, as permissões poderão ser propagadas automaticamente;
  8. Teste: Forneça suporte para teste;
  9. Executar como: permite que um usuário finja ser outro usuário (se permitir) para acessar;
  10. Lembre-se de mim: lembre-se de mim, essa é uma função muito comum, ou seja, depois de fazer o login uma vez, você não precisa fazer login se voltar na próxima vez.

Principais conceitos

1. Assunto usuário atual

  1. Pode ser algo que os rastreadores humanos interagem atualmente com o software
  2. No shiro, podemos nos referir coletivamente a "usuários" em qualquer lugar do código, você pode facilmente obter o Shiro Subject.
  3. Depois de obter o Assunto, você pode obter imediatamente 90% do que deseja fazer com o Shiro para o usuário atual, efetuar login, sair, acessar a sessão, executar verificações de autorização etc.

2. SecurityManager

  1. SecurityManager gerencia as operações de segurança de todos os usuários
  2. Referência a vários componentes de segurança internos aninhados, que é o núcleo da estrutura Shiro
  3. Você pode pensar nisso como o controlador frontal do DispatcherServlet.
  4. Usado para agendar vários serviços de estrutura Shiro

3. Reinos

  1. Realms é o autenticador de informações do usuário e o autenticador de autoridade do usuário
  2. Ao executar autenticação (login) e autorização (controle de acesso), o Shiro encontrará muito conteúdo no Domínio da configuração do aplicativo
  3. Região pode ser entendida como um DAO que lê informações, funções e permissões do usuário
  4. O SecurityManager deseja verificar a identidade e as permissões do usuário e precisa obter as informações correspondentes do Realm para comparação para determinar se a identidade do usuário é legal;
  5. O território pode ser considerado como uma fonte de dados, ou seja, uma fonte de dados segura.

4. arquitetura Shiro

Insira a descrição da imagem aqui

  1. assunto: o assunto pode ser um usuário ou um programa.Para acessar o sistema, o sistema precisa autenticar e autorizar o assunto.
  2. autenticador: o corpo do autenticador efetua a autenticação finalmente através do autenticador.
  3. autorizador: A autorização do corpo principal do autorizador é finalmente realizada através do autenticador.
  4. sessionManager: Os aplicativos Web de gerenciamento de sessões geralmente usam contêineres da Web para gerenciar sessões.O Shiro também fornece um conjunto de métodos de gerenciamento de sessões.
  5. sessionDao: gerenciar dados da sessão através do sessionDao,
  6. cacheManager: o gerenciador de cache armazena em cache principalmente os dados da sessão e da autorização, como o gerenciamento dos dados de autorização por meio do cacheManager e a integração com o ehcache para gerenciar os dados em cache.
  7. região: a região é equivalente a uma fonte de dados e acesso a dados relacionados à autenticação e autorização por meio da região.
  8. criptografia: o gerenciamento de senhas fornece um conjunto de componentes de criptografia / descriptografia para facilitar o desenvolvimento. Por exemplo, forneça hash, criptografia / descriptografia comumente usados ​​e outras funções.

Shiro de correspondência Springboot

  1. Crie um novo projeto springboot
    Insira a descrição da imagem aqui

  2. Importar dependências do springboot-webInsira a descrição da imagem aqui

  3. Para escrever a página de login do controlador e do front-end, você
    precisa integrar o thymeleaf para ingressar nas dependências do thymeleaf

 <!--thymeleaf依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

Insira a descrição da imagem aqui
4. Escreva a página inicial
Escreva login.html, add.html, delete.html, index.html no diretório de modelos para
importar o dtd do timeleaf

xmlns:th="http://www.thymeleaf.org"

login.html
Insira a descrição da imagem aqui

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form th:action="login">
    <input type="text" name="username" value="">
    <input type="password" name="password" value="">
    <input type="submit" value="登录">
</form>
</body>
</html>

index.html
Insira a descrição da imagem aqui
add.html
Insira a descrição da imagem aqui
delete.html
Insira a descrição da imagem aqui
5. Escreva um controlador para ir para a página de login
Insira a descrição da imagem aqui

@RequestMapping({"/","tologin"})
    public String tologin(){
        return "login";
    }
  1. Execute o navegador de inicialização e insira localhost: 8080
    Insira a descrição da imagem aqui
  2. Importe springboot para integrar shiro e mybatis para conectar-se ao banco de dados
    Insira a descrição da imagem aqui
		<!--shiro-整合spring的包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.2</version>
        </dependency>
          <!--shiro整合thymeleaf-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
         <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
  1. Crie um banco de dados para a próxima autenticação e autorização
    Insira a descrição da imagem aqui
    Insira a descrição da imagem aqui
##配置数据驱动信息  (key固定)
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql:///spring_shiro
spring.datasource.username = root
spring.datasource.password =123456

Inclua informações do banco de dados em application.properties
Insira a descrição da imagem aqui

  1. Escreva mapper, service, pojo
    pojo:
    Insira a descrição da imagem aqui
    mapper:
    Insira a descrição da imagem aqui
    service:
    Insira a descrição da imagem aqui
    Impl:
    Insira a descrição da imagem aqui
    controller: teste se ele pode ser consultado
    Insira a descrição da imagem aqui
    Insira a descrição da imagem aqui
  2. Gravar classe de configuração shiroconfig
    Insira a descrição da imagem aqui
  3. Grave a classe de região para herdar a classe AuthorizingRealm e implemente métodos
    Insira a descrição da imagem aqui
  4. Escreva código no shiroConfig
    Insira a descrição da imagem aqui
@Configuration
public class shiroConfig {

    //3. shiroFilterfactaryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//设置安全管理器
        shiroFilterFactoryBean.setLoginUrl("/toLogin");//没有认证后跳到的页面
        /**
         * shiro的内置过滤器
         anon:无需认证就可以访问 默认
         authc:必须认证了才能访问
         user:必须拥有记住我功能才能访问
         perms:必须拥有对某个的权限才能访问
         role:拥有某个角色权限才能访问
         */
        //添加shiro的内置过滤器  设置要拦截的url
        Map<String,String>  filterChainDefinitionMap=new LinkedHashMap<>();//拦截
        filterChainDefinitionMap.put("/add","authc");// /add请求必须认证才能访问
        filterChainDefinitionMap.put("/del","authc");//del必须认证才能访问
        // filterChainDefinitionMap.put("user/**","authc");//支持通配符
        //授权
        filterChainDefinitionMap.put("/add","perms[user:add]");//没有这个user:add权限的会被拦截下来
        filterChainDefinitionMap.put("/del","perms[user:delete]");//没有这个user:delete权限的会被拦截下来
        //未授权的跳转的url
        shiroFilterFactoryBean.setUnauthorizedUrl("/Unauthorized");
        //设置注销的url
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//把设置好的过滤设置到ShiroFilterFactoryBean
        return shiroFilterFactoryBean;
    }

    //2. DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm对象  userRealm
        securityManager.setRealm(userRealm);
        return  securityManager;
    }
    //1. 创建realm对象 自定义的·类
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合shiroDialect:用来整合shiro-thymeleaf
    @Bean
    public ShiroDialect getshiroDialect(){
        return new  ShiroDialect();
    }

}
  1. Escreva código no UserRealm
public class UserRealm extends AuthorizingRealm {

    @Autowired
    InfoService service;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权 doGetAuthorizationInfo");
        SimpleAuthorizationInfo simpInfo = new SimpleAuthorizationInfo();
        //获取当前用户的对象
        Subject subject=SecurityUtils.getSubject();
        Info user = (Info)subject.getPrincipal();//获取用户信息
        simpInfo.addStringPermission(user.getPerm());//获取数据库权限
        return simpInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证 doGetAuthorizationInfo");
        //获取当前的用户
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken userToken=(UsernamePasswordToken)authenticationToken;//获取登录的信息
        //获取用户名 密码  数据库取
        System.out.println(userToken.getUsername());
        Info query = service.queryByName(userToken.getUsername());
        System.out.println(query);
        if(query==null){//没有这个用户
            return null;
        }
        Session session=subject.getSession();//获取用户的session
        session.setAttribute("loginuser",query);

        if(!userToken.getUsername().equals(query.getUsername())){//判断登录的用户名密码 匹配数据库是否正确
            return null;//抛出异常
        }
        //密码认证,shiro做
        return new SimpleAuthenticationInfo(query,query.getPassword(),"");
    }
}

Insira a descrição da imagem aqui
14. Reescreva o controlador
Insira a descrição da imagem aqui

    @RequestMapping("/login")
    public String login(String username,String password){
        try {
            //获取当前的用户
            Subject subject = SecurityUtils.getSubject();
            //封装用户的登录数据
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            subject.login(usernamePasswordToken);//执行登录的方法 没有异常就成功了
            return "index";
        } catch (UnknownAccountException e) {
            /**
             * 异常信息
             * UnknownAccountException :用户名不存在
             * IncorrectCredentialsException:密码错误
             */
            e.printStackTrace();
            System.out.println("用户名不存在");
        }catch (IncorrectCredentialsException e){
            System.out.println("密码错误");
        }
        return "login";
    }

    @RequestMapping("/add")
    public String add(){//跳转页面
        return "add";
    }
    @RequestMapping("/del")
    public String delete(){//跳转页面
        return "delete";
    }
     @RequestMapping("/Unauthorized")
    public String Unauthorized(){//没有权限跳转的url
        return "Unauthorized";
    }
    //注销
    @RequestMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("loginuser",null);//清空session
        return "login";
    }
  1. Escreva uma página
    não autorizada Unauthorized.html
    Insira a descrição da imagem aqui
  2. Execute:
    Insira a descrição da imagem aqui

Insira a descrição da imagem aqui
O usuário root possui apenas permissões user: delete, para que você possa ver apenas o botão
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
delete.O usuário dj possui apenas user: add permissões e você pode ver apenas o
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
usuário add ss. Nenhuma permissão, portanto, nenhum botão é visível.

Também existem métodos de criptografia, como o md5, que podem ser adicionados por você e não serão introduzidos um por um.

Foco: a classe shiroConfig e a classe UserRealm configuram o núcleo **

Acho que você gosta

Origin www.cnblogs.com/joker-dj/p/12690648.html
Recomendado
Clasificación