1. 程式人生 > 實用技巧 >SpringBoot 整合 Shiro

SpringBoot 整合 Shiro

SpringBoot 整合 Shiro

一、新增依賴

pom.xml

<!--shiro-->
<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring-boot-web-starter</artifactId>
	<version>1.5.3</version>
</dependency>
<!--shiro整合thymeleaf-->
<dependency>
	<groupId>com.github.theborakompanioni</groupId>
	<artifactId>thymeleaf-extras-shiro</artifactId>
	<version>2.0.0</version>
</dependency>

二、新增配置檔案

UserRealm.java

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class UserRealm extends AuthorizingRealm
{
    // 授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection)
    {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("user:add");
        info.addStringPermission("user:del");
        return info;
    }
    // 認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken)
    throws AuthenticationException
    {
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        if(!"admin".equals(token.getUsername()))
        {
            return null;
        }
        return new SimpleAuthenticationInfo("","admin","");
    }
}

ShiroConfig.java

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig
{
    private final String PERMS  = "perms[0]";
    /**
     *  Subject 使用者
     *  SecurityManager 管理所有使用者
     *  Realm 連線資料 -- 做驗證
     */
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager)
    {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);

        Map<String,String> filterMap = new LinkedHashMap<>();

        // 授權
        /*
            anon: 無需認證就可訪問
            authc:必須認證才能訪問
            user:必須擁有記住我功能才能訪問
            perms: 擁有對某個資源的許可權才能訪問
            roles:擁有某個角色許可權才能訪問
       */
        filterMap.put("/user/add",perms("user:add"));
        filterMap.put("/user/del",perms("user:del"));
        filterMap.put("/user/query",perms("user:query"));

        bean.setFilterChainDefinitionMap(filterMap);

        bean.setLoginUrl("/login");
        bean.setUnauthorizedUrl("/noauth");
        return bean;
    }
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm)
    {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    @Bean(name = "userRealm")
    public UserRealm userRealm()
    {
        return new UserRealm();
    }

    //整合thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

    /**
     * 拼接 perms[perms]
     * @param perms
     * @return
     */
    private String perms(String perms)
    {
        return PERMS.replace("0",perms);
    }
}

三、Controller 中

controller.java

import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class CommonController
{
    @RequestMapping("/login")
    public String login(String username, String password, Model model)
    {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password,true);
        try
        {
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e)
        {
            model.addAttribute("msg","使用者名稱不存在");
            return "login";
        }catch (IncorrectCredentialsException e)
        {
            model.addAttribute("msg","密碼錯誤");
            return "login";
        }
    }
}

四、HTML 中

<!-- 開啟提示需要在根標籤html加上: xmlns:shiro="http://www.pollix.at/thymeleaf/shiro" -->
<!-- 判斷是否有此許可權 -->
<div shiro:hasPermission="user:add">
    <a th:href="@{/user/add}">add</a>
</div>