日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

配合OAuth2进行单设备登录拦截

發布時間:2023/12/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 配合OAuth2进行单设备登录拦截 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

要進行單設備登錄,在其他地點登錄后,本地的其他操作會被攔截返回登錄界面。

原理就在于要在登錄時在redis中存儲Session,進行操作時要進行Session的比對。

具體實現,假設我們的OAuth 2的登錄調用接口如下:

共享Session,User模塊跟OAuth模塊都要設置

@Configuration @EnableRedisHttpSession public class SessionConfig {}

Feign

@Component @FeignClient("oauth-center") public interface Oauth2Client {/*** 獲取access_token<br>* 這是spring-security-oauth2底層的接口,類TokenEndpoint<br>** @param parameters* @return* @see org.springframework.security.oauth2.provider.endpoint.TokenEndpoint*/@PostMapping(path = "/api-o/oauth/token")Map<String, Object> postAccessToken(@RequestParam Map<String, String> parameters);/*** 刪除access_token和refresh_token<br>* 認證中心的OAuth2Controller方法removeToken** @param access_token*/@DeleteMapping(path = "/api-o/remove_token")void removeToken(@RequestParam("access_token") String access_token);}

Controller

/*** Created by Administrator on 2018/10/19.*/ @Slf4j @RestController public class UserTokenController {@Autowiredprivate Oauth2Client oauth2Client;@Resourceprivate RedisService redisServiceImpl;/*** 系統登陸<br>* 根據用戶名登錄<br>* 采用oauth2密碼模式獲取access_token和refresh_token** @param loginParam* @return*/@PostMapping("/users-anon/sys/logins")public Map<String, Object> login(@RequestBody LoginParam loginParam,HttpServletRequest request) {Map<String, String> parameters = new HashMap<>();parameters.put(OAuth2Utils.GRANT_TYPE, "password");parameters.put(OAuth2Utils.CLIENT_ID, "system"); // parameters.put(OAuth2Utils.CLIENT_ID, "system");parameters.put("client_secret", "system");parameters.put(OAuth2Utils.SCOPE, "app"); // parameters.put("username", username);// 為了支持多類型登錄,這里在username后拼裝上登錄類型parameters.put("username", loginParam.getUsername() + "|" + CredentialType.USERNAME.name());parameters.put("password", loginParam.getPassword());parameters.put("status","200");Map<String, Object> tokenInfo = null;try {tokenInfo = oauth2Client.postAccessToken(parameters);}catch (Exception e){e.printStackTrace();return ResponseUtils.getResult(500,"login failed");} // saveLoginLog(username, "用戶名密碼登陸", BlackIPAccessFilter.getIpAddress(request));return ResponseUtils.getDataResult(tokenInfo);} }

加入Session的存儲

/*** Created by Administrator on 2018/10/19.*/ @Slf4j @RestController public class UserTokenController {@Autowiredprivate Oauth2Client oauth2Client;@Resourceprivate RedisService redisServiceImpl;/*** 系統登陸<br>* 根據用戶名登錄<br>* 采用oauth2密碼模式獲取access_token和refresh_token** @param loginParam* @return*/ @PostMapping("/users-anon/sys/logins")public Map<String, Object> login(@RequestBody LoginParam loginParam, HttpServletRequest request) {Map<String, String> parameters = new HashMap<>();parameters.put(OAuth2Utils.GRANT_TYPE, "password");parameters.put(OAuth2Utils.CLIENT_ID, "system"); // parameters.put(OAuth2Utils.CLIENT_ID, "system");parameters.put("client_secret", "system");parameters.put(OAuth2Utils.SCOPE, "app"); // parameters.put("username", username);// 為了支持多類型登錄,這里在username后拼裝上登錄類型parameters.put("username", loginParam.getUsername() + "|" + CredentialType.USERNAME.name());parameters.put("password", loginParam.getPassword());parameters.put("status","200");Map<String, Object> tokenInfo = null;try {tokenInfo = oauth2Client.postAccessToken(parameters);HttpSession session = request.getSession();String sessionId = UUID.randomUUID().toString();//此處修改為共享Sessionsession.setAttribute("sessionId", sessionId);session.setAttribute("username",loginParam.getUsername());String key = loginParam.getUsername() + "-onlyLogin";redisServiceImpl.set(key,sessionId);redisServiceImpl.expire(key,30 * 60);redisServiceImpl.hset("sessionHash",sessionId,loginParam.getUsername());}catch (Exception e){e.printStackTrace();return ResponseUtils.getResult(500,"login failed");} // saveLoginLog(username, "用戶名密碼登陸", BlackIPAccessFilter.getIpAddress(request));return ResponseUtils.getDataResult(tokenInfo);} }

配置攔截器

@Slf4j @Component public class RedisInterceptor extends HandlerInterceptorAdapter {@Resourceprivate RedisService redisServiceImpl;@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();//讀取共享SessionString requestedSessionId = (String) session.getAttribute("sessionId");String userName = null;response.setCharacterEncoding("utf-8");response.setContentType("text/javascript;charset=utf-8");try {if (!StringUtils.isEmpty(requestedSessionId)) {userName = redisServiceImpl.hget("sessionHash", requestedSessionId);}if (StringUtils.isEmpty(userName)) {response.getWriter().write("{\"message\":\"請先登陸\"}");return false;} else {String cacheSessionId = null;String sessionKey = userName + "-onlyLogin";try {cacheSessionId = redisServiceImpl.get(sessionKey);} catch (Exception e) {e.printStackTrace();}if (StringUtils.isEmpty(cacheSessionId)) {response.getWriter().write("{\"message\":\"請先登陸\"}");return false;} else {if (!cacheSessionId.equals(requestedSessionId)) {response.getWriter().write("{\"message\":\"您的賬號已在別處登陸,請重新登陸\"}");return false;} else {redisServiceImpl.expire(sessionKey, 30 * 60);return super.preHandle(request, response, handler);}}}}catch (Exception e) {e.printStackTrace();}response.getWriter().write("{\"message\":\"服務器忙\"}");return false;} }

攔截器就是為了獲取每次的Session,并且跟redis中的session進行比對,如果session不同,則進行攔截。

@Configuration public class RedisSessionConfig extends WebMvcConfigurerAdapter {@Autowiredprivate RedisInterceptor redisInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(redisInterceptor).excludePathPatterns("/**/users-anon/**").excludePathPatterns("/api-o/oauth/token");super.addInterceptors(registry);} }

這里要配置對登錄的url以及feign的url進行放行,則可以對多地點登錄時,使之前的登錄無法操作。

轉載于:https://my.oschina.net/u/3768341/blog/2885756

總結

以上是生活随笔為你收集整理的配合OAuth2进行单设备登录拦截的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。