1. 程式人生 > >springboot整合shiro的簡單實現

springboot整合shiro的簡單實現

springboot整合shiro的簡單實現


注意:
1.shiro需要自行在doGetAuthenticationInfo方法中進行賬號密碼的校驗
2.ip+埠形式訪問頁面會被shiro攔截,如果沒有登入會被重定向到login頁面,如果登入會被重定向到index頁面(需要配置)
3.登入成功後index頁面跳轉由shiro內部實現(需要配置)
4.退出登入操作由shiro內部實現(需要配置)
5.shiro的許可權控制(按鈕級別),為了在thymeleaf裡使用shiro的標籤的bean,需要在shiro中注入ShiroDialect(需要新增maven),否則無法進入doGetAuthorizationInfo方法!

流程:
當訪問專案時會被shiro攔截進行登入校驗,如果未登入會被重定向到登入頁,如果登入直接放行方法(如果是ip+埠的形式訪問會被重定向到首頁)

方法:
獲取shiro管理的物件方法:
User user = (User) SecurityUtils.getSubject().getPrincipal();

@Controller
public class LoginController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

//  首頁跳轉
    @GetMapping
("/") String toIndex() { return "index"; } // 登入跳轉 @GetMapping("/login") String login() { return "login"; } // 登入 @PostMapping("/ajaxLogin") @ResponseBody String ajaxLogin(String username, String password) { try { //收集實體/憑據資訊 UsernamePasswordToken token =
new UsernamePasswordToken(username, password); Subject subject = SecurityUtils.getSubject(); subject.login(token); } catch (Exception e) { return "error"; } return "success"; } // 測試 @GetMapping("/test") @RequiresPermissions("companyUser:user:save") String test(RedirectAttributes redirectAttributes) { redirectAttributes.addAttribute("a", "a"); redirectAttributes.addAttribute("b", "b"); return "redirect:/test2"; } // 測試 @GetMapping("/test2") @ResponseBody User test2(String a , String b ) { System.out.println("a:"+a +"----------"+"b:"+b ); User user = (User) SecurityUtils.getSubject().getPrincipal(); return user; } }
//自定義驗證器(必要的)
public class MyRealm extends AuthorizingRealm {


    //授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        System.out.println("==================================================================授權");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //存放可放行的許可權
        Set<String> str = new HashSet<>();
        str.add("companyUser:user:save");
        info.setStringPermissions(str);
        return info;
    }

    //驗證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        System.out.println("==================================================================驗證");
        UsernamePasswordToken user = (UsernamePasswordToken) authenticationToken;
        char[] pd = user.getPassword();
        String password = String.valueOf(pd);
        String username = user.getUsername();
        if (!"admin".equals(username)||!"123456".equals(password)) {
            throw new IncorrectCredentialsException("賬號或密碼不正確");
        }
        User user = new User();
        user.setPassword(password);
        user.setUsername(username);
        //第一個引數用來存放在session中的資訊
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

}
//注入驗證器(必要的)
@Configuration
public class ShiroConfiguration {

    //將自己的驗證方式加入容器
    @Bean
    public MyRealm myShiroRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }

    /**
     * ShiroDialect,為了在thymeleaf裡使用shiro的標籤的bean
     * html中使用方法:shiro:hasPermission
     * Maven中新增:
     *          <dependency>
     *             <groupId>com.github.theborakompanioni</groupId>
     *             <artifactId>thymeleaf-extras-shiro</artifactId>
     *             <version>2.0.0</version>
     *         </dependency>
     *
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

    //許可權管理,配置主要是Realm的管理認證
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工廠,設定對應的過濾條件和跳轉條件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map = new HashMap<String, String>();
        //放行路徑
        map.put("/ajaxLogin","anon");
        //登出
        map.put("/logout","logout");
        //對所有使用者認證
        map.put("/**","authc");
        //登入
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首頁
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //錯誤頁面,認證不通過跳轉
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //加入註解的使用,不加入這個註解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}

登入頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form id="loginForm">
        賬號:<input type="text" placeholder="請輸入賬號" name="username">
        密碼:<input type="text" placeholder="請輸入密碼" name="password">
        <input type="button" id="loginBut" value="登入">
    </form>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    $("#loginBut").click(function () {
        $.ajax({
            type: "POST",
            url: "/ajaxLogin",
            data: $("#loginForm").serialize(),
            success: function (r) {
                if ("success" == r) {
                    location.href="/"
                }else{
                    alert("賬號或密碼不正確!");
                }
            }
        });
    })
</script>
</html>

首頁(許可權測試頁)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/test" shiro:hasPermission="companyUser:user:save">登入成功測試(有許可權)</a>
    <a href="/test" >登入成功測試(無許可權)</a>
</body>
</html>
//User物件
/**@Date註解
 * maven新增
 *         <dependency>
 *             <groupId>org.projectlombok</groupId>
 *             <artifactId>lombok</artifactId>
 *         </dependency>
 */
@Data
public class User implements Serializable {
    private String username;
    private String password;
}