시로
Shiro는 Apache의 오픈 소스 프로젝트입니다. 우리는 그것을 Apache Shiro라고합니다. Java 프로젝트를 통해 사용하기 쉬운 보안 프레임 워크로 인증, 승인, 암호화 및 세션 관리를 제공합니다. Spring Security와 마찬가지로 권한 보안 프레임 워크입니다. 그러나 Spring Security와 비교하여 Shiro는 비교적 간단하고 이해하기 쉽고 사용하기 쉬운 권한 부여 방법을 사용합니다. Shiro는 가벼운 프레임 워크입니다. 보안보다 훨씬 간단하며 보안만큼 복잡하지 않습니다. 보다 자세한 소개를 보려면 기본적으로 공식 웹 사이트 (http://shiro.apache.org/)에서 다음 기능을 제공 할 수 있습니다.
(1) 인증 (인증)
(2) 승인 (승인)
(3) 세션 관리 (세션 관리)
(4) 암호화 (암호화)
우선, 인증 서비스, 즉 그녀를 통해 신분증 인증을 완료하여 사용자가 실제 구성원인지 확인할 수 있습니다.
둘째, 공인 서비스는 무뚝뚝하게 말하면 "액세스 제어"서비스, 즉 사용자가 어떤 권한을 식별 할 수 있도록합니다. 무뚝뚝하게 말하면, 사용자가 어떤 역할을하는지 판단하여 어떤 작업 권한을 부여하는 것입니다.
그런 다음 세션 관리 서비스가 있습니다. 현재 독립 세션 관리 프레임 워크는 우리가 익숙한 HTTP 세션과 다릅니다.
마지막으로, 그녀는 암호화 (암호화) 서비스를 제공하여 많은 암호화 알고리즘을 캡슐화합니다.
오늘은 그것에 대해 모든 것을 말하지 않고 대화 관리 기능에 중점을 둘 것입니다. 실제로 이것은 거의 모든 웹이 참여 해야하는 것입니다.
Shiro의 세션 관리 서비스에 대해 이야기하기 전에 이전 세션 관리 방법을 검토하겠습니다.
1. 처음에는 웹 서버의 HTTP 세션 메커니즘을 직접 사용했습니다. 즉, 사용자가 처음으로 들어 오면 웹 컨테이너가 요청에 대한 세션을 생성 한 다음 세션을 저장합니다. 해당 SessionID를 고객에게 쿠키로 전달함으로써.
클라이언트 가이 서버에 요청을 다시 보내면 SessionID가 자동으로 가져옵니다. 그런 다음 웹 서버는 세션이 클라이언트가 가져온 SessionID를 기반으로 메모리에 있는지 여부를 결정합니다 (세션은 만료 시간이 있으며 Web.xml 파일에서 구성 할 수 있음). 해당 세션을 찾을 수없는 경우 세션 만료 시간이 통과되었음을 의미합니다. 이 시점에서 웹 서버는 다시 세션을 작성한 다음 이전과 같이 새 SessionID를 클라이언트에게 전달합니다.
따라서이 메커니즘을 사용하여 프로그램에서 사용자의 로그인 세션을 관리 할 수 있습니다. 예를 들어, 사용자의 첫 번째 로그인이 성공하면 세션에 사용자의 기본 정보를 저장합니다 (예 : session.setAttribute("user", "userInfo") ). 다음에 사용자가 다시 방문하면 사용자 정보를 기반으로 현재 세션에서 사용자 정보를 얻습니다.
( session.getAttribute("user") )는 사용자가 만료되었는지 여부를 결정합니다. 얻을 수없는 경우 사용자에게 다시 로그인하라는 메시지가 표시됩니다.
2. 두 번째 방법은 정보가 캐시, Memecache 또는 Redis와 같은 타사 미디어에 저장되는 장소를 전송하는 것입니다. 이 방법은 주로 분산 시스템의 출현으로 인해 채택됩니다.
이 경우 세션을 직접 생성해야합니다. 일반적으로 정의 된 접두사 ( user:login:token )를 사용하고 userID 또는 타임 스탬프를 추가합니다. 그런 다음이 SessionID를 캐시 키로 사용하고 사용자의 정보를 값으로 사용하여 캐시에 저장하고 무효화 시간을 설정합니다.
jedisclient.set (tokenkey, jsonutil.tojsonstring (userInfo)); jedisclient.expire (tokenkey, token_lose_seconds);
또한 쿠키를 통해 생성 된 토큰 키를 클라이언트에게 전달해야합니다. CookieUtils.setCookie(request, response, "TT_TOKEN", tokenKey);
이런 식으로 사용자가 다음에 방문 할 때 (인터셉터 정의) 쿠키에서 해당 토큰 키를 꺼낸 다음이 토큰 키를 사용하여 캐시로 이동하여 해당 값을 검색 할 수 있습니다. 얻을 수없는 경우 키가 만료되고 사용자가 다시 로그인하라는 메시지가 표시됩니다.
참고 : Tokenkey가 중요합니다. 캐시 측과 클라이언트를 연결하는 허브입니다.
3. 마지막 것은 Shiro 방법이며 아이디어는 비슷합니다. 코드는 매우 간단하므로 코드를 업로드하겠습니다.
1) 새 ApplicationContextShiro.xml 파일 작성 :
<? xml version = "1.0"encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : context = "http://www.springframework.org/schema/context" xmlns : p = "http://www.springframework.org/schema/p"xmlns : aop = "http://www.springframework.org/schema/tx"xmlns : xsi = "http://www.w.3.org/2001/xmscema-instance. xsi : schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/contet http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.spramework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd " id = "shirofilter"> <property name = "securitymanager"ref = "securitymanager"> </property> <property name = "loginUrl"value = "/loginPage"> </property "value ="unauthorizedUrl "value ="/pages/unauthorized.jsp "/> <propertchaindefinitions"> <value>/jcaptcha* =/jcaptcha*. anon </value> </property> </bean> <ean> <속성 이름 = "staticMethod"value = "org.apache.shiro.securityUtils.setSecurityManager"> </property> <property name = "arguments"ref = "securityManager"> </property> </bean> <bean id = "securityManager"> <cachemanager "> cachemanager"ref = "cachemanager". 이름 = "sessionManager"ref = "sessionManager"> </property> </bean> <bean id = "sessionManager"> <property name = "sessionDao"ref = "sessionDao"> </bean> //이 클래스 자체로 구현해야합니다 <bean id = "cachemanager"> </bean> </bean>
2) web.xml에서 해당 필터를 구성하십시오.
<filter> <filter-name> shirofilter </filter-name> <filter-class> org.springframework.web.filter.delegatingFilterProxy </filter-class> <init-param> <param-name> targetFilterLifeCycle </param-name> <param-value> true </param- value> <filter-mapping> <filter-name> shirofilter </filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3) 구현 클래스를 작성하고 AbstractSessionDao를 상속하고 해당 방법을 구현하십시오.
package com.jdd.core.shiro; import com.smart.core.redis.redismanager; import org.apache.shiro.session.session; import org.apache.shiro.session.unknownsessionexception; import org.apache.shiro.session.mgt.eis.abstractsdao; import org.springframework.bean.bean.bean.annotation.autowired; import org.springframework.util.serializationutils; import java.io. @override public void update (세션 세션) unknownsessionexception {redismanager.set (serializationUtils.serialize (session.getId (). toString ()), SerializationUtils.serialize (session)); redismanager.expire (SerializationUtils.serialize (session.getId (). toString ()), 60); } @override public void delete (세션 세션) {redismanager.del (serializationUtils.serialize (session.getId (). toString ())); } @override public collection <session> getActiveSessions () {return new arrayList <세션> (); } @override 보호 직렬화 가능한 docreate (세션 세션) {// 이것은 처음 액세스 할 때 SessionId Serializable Sid = this.generatesSessionID (세션)를 만듭니다. antarssessionId (세션, SID); redismanager.set (SerializationUtils.serialize (session.getId (). toString ()), SerializationUtils.serialize (session)); redismanager.expire (SerializationUtils.serialize (session.getId (). toString ()), 60); 반환 시드; } @override Protected Session Doreadsession (Serializable Serializable) {//이 메소드는 실제로 SessionID를 통해 세션을 읽는 것입니다. 읽을 때마다 실패 시간은 바이트를 재설정해야합니다 [] aa = redismanager.get (SerializationUtils.serialize (serializable.toString ())); 세션 세션 = (세션) SerializationUtils.deserialize (AA); redismanager.set (SerializationUtils.serialize (serializable.toString ()), SerializationUtils.Serialize (세션)); redismanager.expire (SerializationUtils.serialize (serializable.toString ()), 60); 반환 세션; }}4) 다음 단계는 성공적인 로그인 후 논리에서 Shiro 세션을 얻은 다음 사용자 정보를 설정하는 것입니다.
package com.smart.controller; import com.smart.pojo.user; import com.smart.service.userservice; import org.apache.shiro.securityutils; import org.apache.shiro.mgt.securitymanager; import org.apache.shiro.shiro.subject.sublf4j; org.slf4j.loggerfactory; import org.springframework.beans.beans.annotation.autowired; import org.spramework.steretype.controller; import org.springframework.ui.model; import org.springframework.web.bind.annotation javax.servlet.http.htttp.httpservletrequest; import javax.servlet.http.htttp.httpservletresponse;@controller@requestmapping ( "/user") public class usercontroller {@autowired private userervice userervice; @autowired private securitymanager sm; // SecurityManager 개인 로거 로그거 = loggerFactory.getLogger (userController.class); @requestmapping (value = "/loginpage") public String loginpage () {return "user/userLogin"; } @requestMapping (value = "/userLogin", method = requestMethod.post) public String userLogin (@requestParam (value = "name") 문자열 이름, @requestParam (value = "pwd") String Pwd, 모델 모델) {logger.info ( "enter userLogin ..."); user user = userervice.getUserByNameAndPassword (이름, pwd); if (user == null) {logger.info ( "사용자가 존재하지 않습니다 ..."); model.adtattribute ( "login_error", "사용자 이름 또는 비밀번호 오류"); "User/UserLogin"을 반환합니다. } SecurityUtils.SetSecurityManager (SM); 대상 currentuser = security.getSubject (); currentUser.getSession (). setAttribute ( "login_user", user); "리디렉션 :/직원/목록"을 반환합니다. }}Shiro에서 현재 사용자를 가져 오면 테마이며 해당 세션을 받고 사용자 정보를 설정하십시오. HTTP 세션의 운영과 비슷하다고 느끼나요? 하하.
5) 마지막으로, SpringMVC 인터셉터를 정의하여 인터셉터의 해당 세션에서 사용자 정보를 얻습니다. 얻을 수없는 경우 로그인 인터페이스로 이동합니다.
package com.smart.core.shiro; import com.smart.smart.pojo.user; import org.apache.shiro.securityutils; import org.apache.shiro.mgt.securitymanager; import org.apache.shiro.subject.subject; import org.slf4j.logger; org.springframework.bean.beans.annotation.autowired; import org.springframework.web.servlet.handlerinterceptor; import org.springframework.web.servlet.modelandview; import javax.servlet.http.httpervletrequest; import; javax.servlet.http.httpservletresponse; public class logininterceptor implements handlerinterceptor {private logger = loggerfactory.getLogger (logininterceptor.class); @autowired private securitymanager sm; @override public boolean prehandle (httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o) 예외 {logger.info ( "logininterceptor enther ..."); httpservletrequest 요청 = httpservletrequest; httpservletresponse 응답 = httpservletresponse; logger.info ( "요청 uri ===>"+request.getRequesturi ()); // 로그인 페이지에 대한 요청 인 경우 가로 채기되지 않으면 차단되지 않습니다. 그렇지 않으면 (request.getRequesturi (). contains ( "loginpage") || request.getRequesturi ()) {return true; } else {SecurityS.SetSecurityManager (SM); 대상 currentuser = security.getSubject (); Object obj = currentUser.getSession (). getAttribute ( "login_user"); if (obj == null) {response.sendRedirect ( "http : // localhost : 8080/user/loginpage"); 거짓을 반환합니다. } else {user user = (사용자) obj; if (user == null || user.getName () == null) {response.sendRedirect ( "http : // localhost : 8080/user/loginpage"); 거짓을 반환합니다. } else {return true; }}}} @override public void posthandle (httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview)은 예외 {} @override public void aftercompletion (httpserverquest httperverponsconsconse httpservletresponse, 객체 O, 예외 e) 예외 {}} 던지기기본적으로 여기에 있습니다. 홈페이지 정보에 직접 액세스하면 로그인 페이지로 자동 이동합니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.