1. 程式人生 > >shiro整合OAuth2學習體會

shiro整合OAuth2學習體會

OAuth2是一個授權的協議,其使授權的流程變得更加簡單,本文是學習開濤部落格shiro整合OAuth2文章的個人學習體會,可以參考原博主的文章,http://jinnianshilongnian.iteye.com/blog/2038646,裡面有詳細的講解

授權流程圖,網上找

服務端程式碼

1. 授權控制器

package com.github.zhangkaitao.shiro.chapter17.web.controller;

import java.net.URI;
import java.net.URISyntaxException;

import javax.servlet.http.HttpServletRequest
; import javax.servlet.http.HttpServletResponse; import org.apache.oltu.oauth2.as.issuer.MD5Generator; import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl; import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest; import org.apache.oltu.oauth2.as.response.OAuthASResponse; import org.apache.oltu
.oauth2.common.OAuth; import org.apache.oltu.oauth2.common.error.OAuthError; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.OAuthResponse; import org.apache.oltu.oauth
2.common.message.types.ResponseType; import org.apache.oltu.oauth2.common.utils.OAuthUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import com.github.zhangkaitao.shiro.chapter17.Constants; import com.github.zhangkaitao.shiro.chapter17.service.ClientService; import com.github.zhangkaitao.shiro.chapter17.service.OAuthService; /** * <p>User: Zhang Kaitao * <p>Date: 14-2-16 * <p>Version: 1.0 */ @Controller public class AuthorizeController { @Autowired private OAuthService oAuthService; @Autowired private ClientService clientService; @RequestMapping("/authorize") public Object authorize(Model model,HttpServletRequest request) throws URISyntaxException, OAuthSystemException { try { //構建OAuth 授權請求 OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request); //檢查傳入的客戶端id是否正確,通過查詢資料庫表oauth2_client比對。 if (!oAuthService.checkClientId(oauthRequest.getClientId())) { OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST) .setError(OAuthError.TokenResponse.INVALID_CLIENT) .setErrorDescription(Constants.INVALID_CLIENT_DESCRIPTION) .buildJSONMessage(); return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus())); } Subject subject = SecurityUtils.getSubject(); //如果使用者沒有登入,跳轉到服務端的登陸頁面 if(!subject.isAuthenticated()) { if(!login(subject, request)) {//登入失敗時跳轉到服務端的登陸頁面 model.addAttribute("client", clientService.findByClientId(oauthRequest.getClientId()));//根據Id獲取客戶端實體資訊 return "oauth2login"; } } String username = (String)subject.getPrincipal(); //生成授權碼 String authorizationCode = null; //responseType目前僅支援CODE,另外還有TOKEN String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE); if (responseType.equals(ResponseType.CODE.toString())) { OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator()); authorizationCode = oauthIssuerImpl.authorizationCode(); oAuthService.addAuthCode(authorizationCode, username);//把授權碼儲存在cache中 } //進行OAuth響應構建 OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND); //設定授權碼 builder.setCode(authorizationCode); //得到到客戶端重定向地址 String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI); //構建響應 final OAuthResponse response = builder.location(redirectURI).buildQueryMessage(); //根據OAuthResponse返回ResponseEntity響應 HttpHeaders headers = new HttpHeaders(); headers.setLocation(new URI(response.getLocationUri())); return new ResponseEntity(headers, HttpStatus.valueOf(response.getResponseStatus())); } catch (OAuthProblemException e) { //出錯處理 String redirectUri = e.getRedirectUri(); if (OAuthUtils.isEmpty(redirectUri)) { //告訴客戶端沒有傳入redirectUri直接報錯 return new ResponseEntity("OAuth callback url needs to be provided by client!!!", HttpStatus.NOT_FOUND); } //返回錯誤訊息(如?error=) final OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND) .error(e).location(redirectUri).buildQueryMessage(); HttpHeaders headers = new HttpHeaders(); headers.setLocation(new URI(response.getLocationUri())); return new ResponseEntity(headers, HttpStatus.valueOf(response.getResponseStatus())); } } private boolean login(Subject subject, HttpServletRequest request) { if("get".equalsIgnoreCase(request.getMethod())) { return false; } String username = request.getParameter("username"); String password = request.getParameter("password"); if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { return false; } UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); return true; } catch (Exception e) { request.setAttribute("error", "登入失敗:" + e.getClass().getName()); return false; } } }

2. 訪問令牌控制器

package com.github.zhangkaitao.shiro.chapter17.web.controller;

import java.net.URISyntaxException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.github.zhangkaitao.shiro.chapter17.Constants;
import com.github.zhangkaitao.shiro.chapter17.service.OAuthService;
import com.github.zhangkaitao.shiro.chapter17.service.UserService;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-16
 * <p>Version: 1.0
 */
@RestController
public class AccessTokenController {

    @Autowired
    private OAuthService oAuthService;

    @Autowired
    private UserService userService;

    @RequestMapping("/accessToken")
    public HttpEntity token(HttpServletRequest request)
            throws URISyntaxException, OAuthSystemException {

        try {
            //構建OAuth請求
            OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);

            //檢查提交的客戶端id是否正確
            if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
                OAuthResponse response =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                                .setErrorDescription(Constants.INVALID_CLIENT_DESCRIPTION)
                                .buildJSONMessage();
                return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
            }

            // 檢查客戶端安全KEY是否正確,查詢資料庫表oauth2_client,事先服務端資料庫就儲存了客戶端的訪問資訊。見表結構
            if (!oAuthService.checkClientSecret(oauthRequest.getClientSecret())) {
                OAuthResponse response =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                                .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
                                .setErrorDescription(Constants.INVALID_CLIENT_DESCRIPTION)
                                .buildJSONMessage();
                return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
            }
            //獲取客戶端傳入的授權碼
            String authCode = oauthRequest.getParam(OAuth.OAUTH_CODE);
            // 檢查驗證型別,此處只檢查AUTHORIZATION_CODE型別,其他的還有PASSWORD或REFRESH_TOKEN
            if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE).equals(GrantType.AUTHORIZATION_CODE.toString())) {
                if (!oAuthService.checkAuthCode(authCode)) {
                    OAuthResponse response = OAuthASResponse
                            .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                            .setError(OAuthError.TokenResponse.INVALID_GRANT)
                            .setErrorDescription("錯誤的授權碼")
                            .buildJSONMessage();
                    return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
                }
            }

            //生成Access Token
            OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
            final String accessToken = oauthIssuerImpl.accessToken();
            //把access Token儲存在cache,這樣可以通過cache配置過期時間來使accessToken過期,
            //當然也可以把accessToken儲存在資料庫,通過建立時間和當前時間區間判斷,方法多種
            oAuthService.addAccessToken(accessToken, oAuthService.getUsernameByAuthCode(authCode));


            //生成OAuth響應
            OAuthResponse response = OAuthASResponse
                    .tokenResponse(HttpServletResponse.SC_OK)
                    .setAccessToken(accessToken)
                    .setExpiresIn(String.valueOf(oAuthService.getExpireIn()))
                    .buildJSONMessage();

            //根據OAuthResponse生成ResponseEntity
            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

        } catch (OAuthProblemException e) {
            //構建錯誤響應
            OAuthResponse res = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
                    .buildJSONMessage();
            return new ResponseEntity(res.getBody(), HttpStatus.valueOf(res.getResponseStatus()));
        }
    }
}

3. 資源控制器

package com.github.zhangkaitao.shiro.chapter17.web.controller;

import com.github.zhangkaitao.shiro.chapter17.Constants;
import com.github.zhangkaitao.shiro.chapter17.service.OAuthService;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.common.utils.OAuthUtils;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.apache.oltu.oauth2.rs.response.OAuthRSResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-16
 * <p>Version: 1.0
 */
@RestController
public class UserInfoController {

    @Autowired
    private OAuthService oAuthService;

    @RequestMapping("/userInfo")
    public HttpEntity userInfo(HttpServletRequest request) throws OAuthSystemException {
        try {

            //構建OAuth資源請求
            OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request, ParameterStyle.QUERY);
            //獲取Access Token
            String accessToken = oauthRequest.getAccessToken();

            //驗證Access Token
            if (!oAuthService.checkAccessToken(accessToken)) {
                // 如果不存在/過期了,返回未驗證錯誤,需重新驗證
                OAuthResponse oauthResponse = OAuthRSResponse
                        .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                        .setRealm(Constants.RESOURCE_SERVER_NAME)
                        .setError(OAuthError.ResourceResponse.INVALID_TOKEN)
                        .buildHeaderMessage();

                HttpHeaders headers = new HttpHeaders();
                headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE));
                return new ResponseEntity(headers, HttpStatus.UNAUTHORIZED);
            }
            //返回使用者名稱,在cache裡獲取
            String username = oAuthService.getUsernameByAccessToken(accessToken);
            return new ResponseEntity(username, HttpStatus.OK);
        } catch (OAuthProblemException e) {
            //檢查是否設定了錯誤碼
            String errorCode = e.getError();
            if (OAuthUtils.isEmpty(errorCode)) {
                OAuthResponse oauthResponse = OAuthRSResponse
                        .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                        .setRealm(Constants.RESOURCE_SERVER_NAME)
                        .buildHeaderMessage();

                HttpHeaders headers = new HttpHeaders();
                headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE));
                return new ResponseEntity(headers, HttpStatus.UNAUTHORIZED);
            }

            OAuthResponse oauthResponse = OAuthRSResponse
                    .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                    .setRealm(Constants.RESOURCE_SERVER_NAME)
                    .setError(e.getError())
                    .setErrorDescription(e.getDescription())
                    .setErrorUri(e.getUri())
                    .buildHeaderMessage();

            HttpHeaders headers = new HttpHeaders();
            headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE));
            return new ResponseEntity(HttpStatus.BAD_REQUEST);
        }
    }
}

客戶端程式碼

客戶端授權過程的攔截器

package com.github.zhangkaitao.shiro.chapter18.oauth2;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-18
 * <p>Version: 1.0
 */
public class OAuth2AuthenticationFilter extends AuthenticatingFilter {

    //oauth2 authc code引數名
    private String authcCodeParam = "code";
    //客戶端id
    private String clientId;
    //伺服器端登入成功/失敗後重定向到的客戶端地址
    private String redirectUrl;
    //oauth2伺服器響應型別
    private String responseType = "code";

    private String failureUrl;

    public void setAuthcCodeParam(String authcCodeParam) {
        this.authcCodeParam = authcCodeParam;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }

    public void setResponseType(String responseType) {
        this.responseType = responseType;
    }

    public void setFailureUrl(String failureUrl) {
        this.failureUrl = failureUrl;
    }

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String code = httpRequest.getParameter(authcCodeParam);
        return new OAuth2Token(code);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {


        String error = request.getParameter("error");
        String errorDescription = request.getParameter("error_description");
        if(!StringUtils.isEmpty(error)) {//如果服務端返回了錯誤,也就是服務端裡檢查不通過進入if裡返回的錯誤
            WebUtils.issueRedirect(request, response, failureUrl + "?error=" + error + "error_description=" + errorDescription);
            return false;
        }

        Subject subject = getSubject(request, response);
        if(!subject.isAuthenticated()) {
            if(StringUtils.isEmpty(request.getParameter(authcCodeParam))) {
                //如果使用者沒有身份驗證,且沒有auth code,則重定向到服務端授權,即訪問AuthorizeController的authorize方法
                saveRequestAndRedirectToLogin(request, response);
                return false;
            }
        }

        return executeLogin(request, response);
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
                                     ServletResponse response) throws Exception {
        issueSuccessRedirect(request, response);
        return false;
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request,
                                     ServletResponse response) {
        Subject subject = getSubject(request, response);
        if (subject.isAuthenticated() || subject.isRemembered()) {
            try {
                issueSuccessRedirect(request, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                WebUtils.issueRedirect(request, response, failureUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

自定義認證

package com.github.zhangkaitao.shiro.chapter18.oauth2;

import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-18
 * <p>Version: 1.0
 */
public class OAuth2Realm extends AuthorizingRealm {

    private String clientId;
    private String clientSecret;
    private String accessTokenUrl;
    private String userInfoUrl;
    private String redirectUrl;

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }

    public void setAccessTokenUrl(String accessTokenUrl) {
        this.accessTokenUrl = accessTokenUrl;
    }

    public void setUserInfoUrl(String userInfoUrl) {
        this.userInfoUrl = userInfoUrl;
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;//表示此Realm只支援OAuth2Token型別
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        OAuth2Token oAuth2Token = (OAuth2Token) token;
        String code = oAuth2Token.getAuthCode();
        //下面這段程式碼是解決評論裡說的那個bug的一種方式。
        Subject currentUser = SecurityUtils.getSubject();    
        Session session = currentUser.getSession();  
        if(code!=null){//第一次code不是null,放到session裡 
            session.setAttribute("code", code);  
        }else{//第二次 code是null,從session裡拿。
            code=(String) session.getAttribute("code");  
        }  
        //上面是評論裡某人修復bug的一種方式
        String username = extractUsername(code);

        SimpleAuthenticationInfo authenticationInfo =
                new SimpleAuthenticationInfo(username, code, getName());
        return authenticationInfo;
    }

    private String extractUsername(String code) {

        try {
            OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

            OAuthClientRequest accessTokenRequest = OAuthClientRequest
                    .tokenLocation(accessTokenUrl)
                    .setGrantType(GrantType.AUTHORIZATION_CODE)
                    .setClientId(clientId)
                    .setClientSecret(clientSecret)
                    .setCode(code)
                    .setRedirectURI(redirectUrl)
                    .buildQueryMessage();

            OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);

            String accessToken = oAuthResponse.getAccessToken();
            Long expiresIn = oAuthResponse.getExpiresIn();

            OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(userInfoUrl)
                    .setAccessToken(accessToken).buildQueryMessage();

            OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
            String username = resourceResponse.getBody();
            return username;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OAuth2AuthenticationException(e);
        }
    }
}

自定義token

package com.github.zhangkaitao.shiro.chapter18.oauth2;

import org.apache.shiro.authc.AuthenticationToken;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-18
 * <p>Version: 1.0
 */
public class OAuth2Token implements AuthenticationToken {

    public OAuth2Token(String authCode) {
        this.authCode = authCode;
    }

    private String authCode;
    private String principal;

    public String getAuthCode() {
        return authCode;
    }

    public void setAuthCode(String authCode) {
        this.authCode = authCode;
    }

    public String getPrincipal() {
        return principal;
    }

    public void setPrincipal(String principal) {
        this.principal = principal;
    }

    public Object getCredentials() {
        return authCode;
    }
}

配置檔案

<!-- Realm實現 -->
<bean id="oAuth2Realm" class="com.github.zhangkaitao.shiro.chapter18.oauth2.OAuth2Realm">
        <property name="cachingEnabled" value="true"/>
        <
            
           

相關推薦

shiro整合OAuth2學習體會

OAuth2是一個授權的協議,其使授權的流程變得更加簡單,本文是學習開濤部落格shiro整合OAuth2文章的個人學習體會,可以參考原博主的文章,http://jinnianshilongnian.iteye.com/blog/2038646,裡面有詳細的講解

SpringBoot+shiro整合學習之登入認證和許可權控制

學習任務目標 使用者必須要登陸之後才能訪問定義連結,否則跳轉到登入頁面。 對連結進行許可權控制,只有噹噹前登入使用者有這個連結訪問許可權才可以訪問,否則跳轉到指定頁面。 輸入錯誤密碼使用者名稱或則使用者被設定為靜止登入,返回相應json串資訊 匯

Shiro學習--實際應用(SSM+Shiro)整合

可以參考Apache Shiro官網的文件:http://shiro.apache.org/reference.html 程式碼下載地址:https://download.csdn.net/download/qq_42969074/10810610 Apache Shiro是一個功能強大

shiro學習shiro整合SpringMVC的web專案

這篇文章只是介紹了shiro與springweb專案進行的整合,並沒有涉及到認證的實現,如果您需要認證的相關實現,請看下我的下一篇:Shiro實現登入和退出 一、準備環境 與其它java開源框架類似,將shiro的jar包加入專案就可以使用shiro提供的功能了。shi

Python2.7 學習體會 @classmethod @staticmethod @property 之間的關系

bject 關系 rom sel def 實例 rop take 新的 先來一個實例場景,然後測試,比較,不懂的話到網上找資料: #!/usr/bin/env python #!/usr/bin/env python class Date(object): def

Python2.7 學習體會 @classmethod @staticmethod @property 之間的關系二

普通 ear self static bject 代碼片段 split 本質 valid 先到百度找了一下資料,引用個重點,對比昨天實例來理解:引用:http://blog.csdn.net/carolzhang8406/article/details/6856817在Py

第六七章學習體會-----(第六次)

可用 nbsp 關註 授權 體會 發的 持續交付 第七章 變化 在這周我看了第六章敏捷流程跟第七章MSF。並有了以下學習總結。 敏捷這個詞聽起來就是反應靈敏迅速而有效,而在軟件按工程裏,敏捷不同於現有做法之處在於,敏捷的價值觀和流程是個人和交流、可用的軟件、與客戶合作、響應

學習體會

學習方法 java 天都 能力 平衡 學習c#已經有段時間了,當初在c#和java之間來回的平衡,最後選擇了c#。想想現在經歷的過程,走的彎路。不免有些笑自己,以前總覺得別人聰明,其實不然,因為別人的接受程度,學習方法,和別人交流,善於總結,勞逸結合程度,分析問題能力,平常的積累,還有

css學習體會之——塊級元素,行內元素長寬設置

寬高 lec 實戰 display 所有 splay 但是 isp 內聯元素 在做一些實戰的布局時,總會發現一些元素設置寬高有用,一些元素沒有用。下面來總結一下: (1)塊級元素:所有的會級元素設置寬高都有效 (2)內聯元素:一般的內聯元素設置寬高沒有用,但是一些特殊的,如

信安軟考學習體會

軟考 2017年5月20日,我參加了信息安全工程師考試。考試結果還算可以,下面介紹一下學習感受。 一 參加了51cto的培訓。感覺老師的培訓視頻很好。特別是密碼學的朱老師,講課重點清晰。之前沒有接觸過密碼學,掌握了老師講的重點,考試的時候基本沒有超出強調的範圍。 二 我是為

Shiro整合Spring

static actor rate utf-8 -i pen aso not exp 首先需要添加shiro的spring整合包。 要想在WEB應用中整合Spring和Shiro的話,首先需要添加一個由spring代理的過濾器如下: <!-- The filter-

python學習體會1

open -- 需要 python學習 相對路徑 pri read 執行命令 方法 今天 學習了如何引用模塊,主要有:sys.py os.py 在sys.py模塊中以下方法需要先熟悉一下: import sys print(sys.path) #打印環境變量 prin

20165302第一周學習體會

cnblogs 自己 image 開始 bin文件 截圖 src gpo ... 20165302第一周學習總結 用了三天多的時間做完了本次作業,其中有很多時間都花在了win10系統更新上面T_T,然而最後只用了Git bash....雖然中間遇到很多問題,但通過自己和同學

Spring Boot整合MyBatis學習總結

Spring Boot MyBatis druid數據源 druid sql監控 公司的很多項目都陸陸續續引入了Spring Boot,通過對Spring Boot的接觸了解發現其真的是大大地簡化了開發、簡化了依賴配置,很多功能註解一下就可以實現,真的是太方便了。下面記錄了一個Sp

【cocos2dx中Node類getParent和getChildByTag()】學習體會

mil 提高 cos cleanup HR -c ldr 12px 而不是 參考http://cn.cocos2d-x.org/doc/cocos2d-x-3.0/

業務邏輯:五、完成認證用戶的動態授權功能 六、完成Shiro整合Ehcache緩存權限數據

nbsp 數據 屬性 查詢 添加 系統 tro 系統管 核心 一、 完成認證用戶的動態授權功能 提示:根據當前認證用戶查詢數據庫,獲取其對應的權限,為其授權 操作步驟: 在realm的授權方法中通過使用principals對象獲取到當前登錄用戶 創建一個授權信息對象

教你 Shiro 整合 SpringBoot,避開各種坑

法則 從數據 協議 ret ppi 擁有 result 註入 nag 最近搞了下 Shiro 安全框架,找了一些網上的博客文章,但是一到自己實現的時候就遇到了各種坑,需要各種查資料看源碼以及各種測試。 那麽這篇文章就教大家如何將 Shiro 整合到 SpringBoot

spring與shiro整合

web.xml map life servle cti 我認 ref init for spring與shiro整合 (1)加入所需要是jar包 (2)配置shiro Filter(web.xml) <!-- shiro過慮器,DelegatingFilte

springboot+shiro整合教程

sco actor attr run max 修改 authz prope ava 本教程整合環境: java8 maven 開發工具: idea 版本: springboot 1.5.15.RELEASE 註: 1.本教程數據操作是模擬數據庫操作,並沒有真正進行持

對二分法的學習體會以及關於結對編程的體驗分享

進一步 計算機 我們 思想 == article 利用 quick 函數 對二分法的學習體會以及關於結對編程的體驗分享 1) 二分搜索技術 二分搜索算法是運用分治策略的典型例子。二分搜索方法充分利用了元素間的次序關系,采用分治策略,可在最壞的情況下用O(logn)時間完成