shiro 권한 검증 및 session 공유 실현
12846 단어 Java
import java.util.List;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.huawei.hicloud.service.UserService;
/**
* /
*
* @author
*
*/
public class MyShiroRealm extends AuthorizingRealm {
private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
@Autowired
private UserService userService;
/**
*
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("##### doGetAuthorizationInfo args: " + principalCollection);
//
String username = (String) principalCollection.getPrimaryPrincipal();
//
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
List roles = userService.getRoles(username);
simpleAuthorizationInfo.addRoles(roles);
for (String role : roles) {
List permissions = userService.getPermissions(role);
simpleAuthorizationInfo.addStringPermissions(permissions);
}
return simpleAuthorizationInfo;
}
/**
*
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
logger.info("##### doGetAuthenticationInfo args: " + authenticationToken);
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//
String userName = token.getUsername();
char[] password = token.getPassword();
// , ,
//
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, password,
ByteSource.Util.bytes(userName), getName());
return authenticationInfo;
}
}
2. SessionManager
import java.io.Serializable;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;
public class MySessionManager extends DefaultWebSessionManager {
private static final String AUTHORIZATION = "X-Auth-Token";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
public MySessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
// Authorization sessionId
if (!StringUtils.isEmpty(id)) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
} else {
// cookie sessionId
return super.getSessionId(request, response);
}
}
}
3. Session Dao 재 작성 session 첨삭 개선 실현
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSON;
import com.huawei.hicloud.components.jedis.JedisClient;
public class RedisSessionDao extends EnterpriseCacheSessionDAO {
private static final Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);
/** Session , : */
private static final Integer SESSION_TIMEOUT = 30*60;
@Autowired
private JedisClient jedisClient;
// session,
@Override
protected Serializable doCreate(Session session) {
logger.info("### doCreate session: " + JSON.toJSONString(session));
Serializable sessionId = super.doCreate(session);
byte[] key = sessionId.toString().getBytes();
jedisClient.set(key, sessionToByte(session));
jedisClient.expire(key, SESSION_TIMEOUT);
return sessionId;
}
// session
@Override
protected Session doReadSession(Serializable sessionId) {
logger.info("### doReadSession sessionId: {}", sessionId);
// session,
Session session = super.doReadSession(sessionId);
if (session == null) {
byte[] key = sessionId.toString().getBytes();
byte[] bytes = jedisClient.get(key);
if (bytes != null && bytes.length > 0) {
session = byteToSession(bytes);
}
jedisClient.expire(key, SESSION_TIMEOUT);
}
return session;
}
// session
@Override
protected void doUpdate(Session session) {
logger.info("### doUpdate session: " + JSON.toJSONString(session));
super.doUpdate(session);
byte[] key = session.getId().toString().getBytes();
jedisClient.set(key, sessionToByte(session));
jedisClient.expire(key, SESSION_TIMEOUT);
}
// session
@Override
protected void doDelete(Session session) {
logger.info("### doDelete session: " + JSON.toJSONString(session));
super.doDelete(session);
jedisClient.del(session.getId().toString().getBytes());
}
// session byte redis
public byte[] sessionToByte(Session session) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] bytes = null;
try {
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(session);
bytes = bo.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
// byte session
public Session byteToSession(byte[] bytes) {
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
ObjectInputStream in;
SimpleSession session = null;
try {
in = new ObjectInputStream(bi);
session = (SimpleSession) in.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return session;
}
}
4. ShiroConfiguration import java.util.LinkedHashMap;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.huawei.hicloud.components.shiro.MySessionManager;
import com.huawei.hicloud.components.shiro.MyShiroRealm;
import com.huawei.hicloud.components.shiro.RedisSessionDao;
@Configuration
public class ShiroConfiguration {
/**
* Realm /
* @return
*/
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
/**
* Redis session
* @return
*/
@Bean
public RedisSessionDao redisSessionDao() {
return new RedisSessionDao();
}
/**
* SessionManager
* SessionDAO , session
* @return
*/
@Bean
public SessionManager sessionManager() {
MySessionManager mySessionManager = new MySessionManager();
mySessionManager.setSessionDAO(redisSessionDao());
mySessionManager.setGlobalSessionTimeout(30 * 60 * 1000);
return mySessionManager;
}
/**
* SecurityManager
* / /session/
* @return
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
securityManager.setSessionManager(sessionManager());
//securityManager.setCacheManager(cacheManager);
return securityManager;
}
/**
* Shiro filter
* @param securityManager
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();
//
filterChainDefinitionMap.put("/logout", "logout");
//
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/ajaxLogin", "anon");
filterChainDefinitionMap.put("/login", "anon");
// url
filterChainDefinitionMap.put("/**", "authc");
//
shiroFilterFactoryBean.setLoginUrl("/login");
//
shiroFilterFactoryBean.setSuccessUrl("/index");
// ,
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* shiro
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
}
5. 로그 인 테스트
Realm 에 가서 인증 을 받 습 니 다.
import java.util.HashMap;
import java.util.Map;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Map login(@RequestBody Map params) {
HashMap result = new HashMap<>();
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("shiro", "123456");
try {
subject.login(token);
result.put("token", subject.getSession().getId() + "");
result.put("msg", " ");
} catch (IncorrectCredentialsException e) {
result.put("msg", " ");
} catch (LockedAccountException e) {
result.put("msg", " , ");
} catch (AuthenticationException e) {
result.put("msg", " ");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
6. 권한 부여 테스트
import java.util.HashMap;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ShiroController {
@RequiresRoles("admin")
@RequiresPermissions("rs:view")
@RequestMapping(value="/shiro", method=RequestMethod.GET)
public Map shiro() {
HashMap resultMap = new HashMap<>();
resultMap.put("msg", "Hello shiro!");
return resultMap;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.