Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
shop-Mall
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
licc
shop-Mall
Commits
71d94aa2
Commit
71d94aa2
authored
4 years ago
by
liqin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bug fixed
parent
9c951d26
master
branch4
branch5
No related merge requests found
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
341 additions
and
157 deletions
+341
-157
AuthToken.java
...admin/src/main/java/cn/wisenergy/web/shiro/AuthToken.java
+0
-1
ShiroConfig.java
...min/src/main/java/cn/wisenergy/web/shiro/ShiroConfig.java
+33
-19
AuthFilter.java
...c/main/java/cn/wisenergy/web/shiro/filter/AuthFilter.java
+137
-137
JwtFilter.java
...rc/main/java/cn/wisenergy/web/shiro/filter/JwtFilter.java
+171
-0
No files found.
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shiro/AuthToken.java
View file @
71d94aa2
package
cn
.
wisenergy
.
web
.
shiro
;
package
cn
.
wisenergy
.
web
.
shiro
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authc.AuthenticationToken
;
/**
/**
...
...
This diff is collapsed.
Click to expand it.
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shiro/ShiroConfig.java
View file @
71d94aa2
package
cn
.
wisenergy
.
web
.
shiro
;
package
cn
.
wisenergy
.
web
.
shiro
;
import
cn.wisenergy.web.shiro.filter.AuthFilter
;
import
cn.wisenergy.web.shiro.filter.AuthRealm
;
import
cn.wisenergy.web.shiro.filter.AuthRealm
;
import
cn.wisenergy.web.shiro.filter.JwtFilter
;
import
org.apache.shiro.mgt.DefaultSessionStorageEvaluator
;
import
org.apache.shiro.mgt.DefaultSubjectDAO
;
import
org.apache.shiro.mgt.SecurityManager
;
import
org.apache.shiro.mgt.SecurityManager
;
import
org.apache.shiro.spring.LifecycleBeanPostProcessor
;
import
org.apache.shiro.spring.LifecycleBeanPostProcessor
;
import
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
;
import
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
;
...
@@ -10,6 +12,7 @@ import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
...
@@ -10,6 +12,7 @@ import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import
org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
;
import
org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.DependsOn
;
import
javax.servlet.Filter
;
import
javax.servlet.Filter
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -18,6 +21,7 @@ import java.util.Map;
...
@@ -18,6 +21,7 @@ import java.util.Map;
/**
/**
* shiro配置类
* shiro配置类
*
* @author 86187
* @author 86187
*/
*/
@Configuration
@Configuration
...
@@ -48,7 +52,7 @@ public class ShiroConfig {
...
@@ -48,7 +52,7 @@ public class ShiroConfig {
// 自定义的过滤器
// 自定义的过滤器
Map
<
String
,
Filter
>
filterMap
=
new
HashMap
<>();
Map
<
String
,
Filter
>
filterMap
=
new
HashMap
<>();
// map里面key值要为过滤器的名称,value为过滤器对象
// map里面key值要为过滤器的名称,value为过滤器对象
filterMap
.
put
(
"oauth2"
,
new
Auth
Filter
());
filterMap
.
put
(
"oauth2"
,
new
Jwt
Filter
());
// 将自定义的过滤器加入到过滤器集合中
// 将自定义的过滤器加入到过滤器集合中
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
...
@@ -73,7 +77,7 @@ public class ShiroConfig {
...
@@ -73,7 +77,7 @@ public class ShiroConfig {
filterChainDefinitionMap
.
put
(
"/**"
,
"oauth2"
);
// 其他路径均需要身份认证,一般位于最下面,优先级最低
filterChainDefinitionMap
.
put
(
"/**"
,
"oauth2"
);
// 其他路径均需要身份认证,一般位于最下面,优先级最低
// 设置拦截器
// 设置拦截器
shiroFilterFactoryBean
.
setFilterChainDefinitionMap
(
filterChainDefinitionMap
);
shiroFilterFactoryBean
.
setFilterChainDefinitionMap
(
filterChainDefinitionMap
);
return
shiroFilterFactoryBean
;
return
shiroFilterFactoryBean
;
}
}
...
@@ -85,34 +89,44 @@ public class ShiroConfig {
...
@@ -85,34 +89,44 @@ public class ShiroConfig {
return
new
LifecycleBeanPostProcessor
();
return
new
LifecycleBeanPostProcessor
();
}
}
@Bean
@Bean
(
name
=
"authRealm"
)
public
static
DefaultAdvisorAutoProxyCreator
getDefaultAdvisorAutoProxyCreator
()
{
@DependsOn
(
"lifecycleBeanPostProcessor"
)
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
=
new
DefaultAdvisorAutoProxyCreator
();
public
AuthRealm
authRealm
()
{
defaultAdvisorAutoProxyCreator
.
setUsePrefix
(
true
);
return
new
AuthRealm
();
return
defaultAdvisorAutoProxyCreator
;
}
}
/**
/**
* 配置加密匹配,使用MD5的方式,进行1024次加密
* securityManager 不用直接注入shiroDBRealm,可能会导致事务失效
* 解决方法见 handleContextRefresh
* http://www.debugrun.com/a/NKS9EJQ.html
*/
*/
// @Bean
// public HashedCredentialsMatcher hashedCredentialsMatcher() {
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName("MD5");
// hashedCredentialsMatcher.setHashIterations(1024);
// return hashedCredentialsMatcher;
// }
@Bean
(
"securityManager"
)
@Bean
(
"securityManager"
)
public
SecurityManager
securityManager
(
AuthRealm
authRealm
)
{
public
SecurityManager
securityManager
(
AuthRealm
authRealm
)
{
DefaultWebSecurityManager
securityManager
=
new
DefaultWebSecurityManager
();
DefaultWebSecurityManager
securityManager
=
new
DefaultWebSecurityManager
();
securityManager
.
setRealm
(
authRealm
);
securityManager
.
setRealm
(
authRealm
);
securityManager
.
setRememberMeManager
(
null
);
securityManager
.
setRememberMeManager
(
null
);
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO
subjectDAO
=
new
DefaultSubjectDAO
();
DefaultSessionStorageEvaluator
defaultSessionStorageEvaluator
=
new
DefaultSessionStorageEvaluator
();
defaultSessionStorageEvaluator
.
setSessionStorageEnabled
(
false
);
subjectDAO
.
setSessionStorageEvaluator
(
defaultSessionStorageEvaluator
);
securityManager
.
setSubjectDAO
(
subjectDAO
);
return
securityManager
;
return
securityManager
;
}
}
/**
@Bean
* 开启Shiro的注解
@DependsOn
(
"lifecycleBeanPostProcessor"
)
*/
public
static
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
()
{
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
=
new
DefaultAdvisorAutoProxyCreator
();
defaultAdvisorAutoProxyCreator
.
setUsePrefix
(
true
);
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
defaultAdvisorAutoProxyCreator
.
setProxyTargetClass
(
true
);
return
defaultAdvisorAutoProxyCreator
;
}
@Bean
@Bean
public
AuthorizationAttributeSourceAdvisor
authorizationAttributeSourceAdvisor
(
SecurityManager
securityManager
)
{
public
AuthorizationAttributeSourceAdvisor
authorizationAttributeSourceAdvisor
(
SecurityManager
securityManager
)
{
AuthorizationAttributeSourceAdvisor
advisor
=
new
AuthorizationAttributeSourceAdvisor
();
AuthorizationAttributeSourceAdvisor
advisor
=
new
AuthorizationAttributeSourceAdvisor
();
...
...
This diff is collapsed.
Click to expand it.
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shiro/filter/AuthFilter.java
View file @
71d94aa2
This diff is collapsed.
Click to expand it.
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shiro/filter/JwtFilter.java
0 → 100644
View file @
71d94aa2
package
cn
.
wisenergy
.
web
.
shiro
.
filter
;
import
cn.wisenergy.common.enums.RespCodeEnum
;
import
cn.wisenergy.common.utils.HttpContextUtils
;
import
cn.wisenergy.common.utils.exception.Result
;
import
cn.wisenergy.web.shiro.AuthToken
;
import
com.alibaba.fastjson.JSON
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authz.UnauthorizedException
;
import
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* 执行流程preHandle->isAccessAllowed->isLoginAttempt->executeLogin->onLoginSuccess
*/
public
class
JwtFilter
extends
BasicHttpAuthenticationFilter
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
JwtFilter
.
class
);
/**
* 最先执行的方法
*/
@Override
protected
boolean
preHandle
(
ServletRequest
request
,
ServletResponse
response
)
throws
Exception
{
return
super
.
preHandle
(
request
,
response
);
}
/**
* 这里重写了父类的方法,使用我们自己定义的Token类,提交给shiro。
* 这个方法返回null的话会直接抛出异常,进入isAccessAllowed() 的异常处理逻辑。
*/
@Override
protected
AuthenticationToken
createToken
(
ServletRequest
request
,
ServletResponse
response
)
{
//获取请求token
String
token
=
((
HttpServletRequest
)
request
).
getHeader
(
"Authorization"
);
if
(
StringUtils
.
isBlank
(
token
))
{
return
null
;
}
return
new
AuthToken
(
token
);
}
/**
* 这里我们详细说明下为什么最终返回的都是true,即允许访问
* 例如我们提供一个地址 GET /article
* 登入用户和游客看到的内容是不同的
* 如果在这里返回了false,请求会被直接拦截,用户看不到任何东西
* 所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入
* 如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可
* 但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大
*/
@Override
protected
boolean
isAccessAllowed
(
ServletRequest
request
,
ServletResponse
response
,
Object
mappedValue
)
{
if
(
isLoginAttempt
(
request
,
response
))
{
//if (!isLoginAttempt(request, response) || !executeLogin(request,response)) {
try
{
executeLogin
(
request
,
response
);
}
catch
(
UnauthorizedException
|
AuthenticationException
e
)
{
return
false
;
}
}
return
true
;
}
/**
* 判断用户是否想要登入。
* 检测header里面是否包含Authorization字段即可
*/
@Override
protected
boolean
isLoginAttempt
(
ServletRequest
request
,
ServletResponse
response
)
{
HttpServletRequest
req
=
(
HttpServletRequest
)
request
;
String
authorization
=
req
.
getHeader
(
"Authorization"
);
return
authorization
!=
null
;
}
/**
*
*/
@Override
protected
boolean
executeLogin
(
ServletRequest
servletRequest
,
ServletResponse
servletResponse
)
{
HttpServletRequest
request
=
(
HttpServletRequest
)
servletRequest
;
String
authorization
=
getRequestToken
(
request
);
if
(
StringUtils
.
isNotBlank
(
authorization
))
{
if
(
authorization
.
startsWith
(
"Bearer "
))
{
authorization
=
authorization
.
substring
(
7
);
}
}
AuthToken
token
=
new
AuthToken
(
authorization
);
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
getSubject
(
servletRequest
,
servletResponse
).
login
(
token
);
// 如果没有抛出异常则代表登入成功,返回true
return
true
;
}
@Override
protected
boolean
onAccessDenied
(
ServletRequest
request
,
ServletResponse
response
)
throws
IOException
{
if
(
isLoginRequest
(
request
,
response
))
{
return
true
;
}
else
{
//获取请求token,如果token不存在,直接返回40101
String
token
=
getRequestToken
((
HttpServletRequest
)
request
);
if
(
StringUtils
.
isBlank
(
token
))
{
HttpServletResponse
httpResponse
=
(
HttpServletResponse
)
response
;
//这里是个坑,如果不设置的接受的访问源,那么前端都会报跨域错误,因为这里还没到corsConfig里面
httpResponse
.
setHeader
(
"Access-Control-Allow-Origin"
,
HttpContextUtils
.
getOrigin
());
httpResponse
.
setHeader
(
"Access-Control-Allow-Methods"
,
"GET,POST,OPTIONS,PUT,DELETE"
);
httpResponse
.
setHeader
(
"Access-Control-Allow-Credentials"
,
"true"
);
httpResponse
.
setCharacterEncoding
(
"UTF-8"
);
httpResponse
.
setContentType
(
"application/json;charset=UTF-8"
);
httpResponse
.
setStatus
(
401
);
Result
result
=
new
Result
();
result
.
setResult
(
Result
.
RESULT_FLG
.
FAIL
.
getValue
());
result
.
setErrorCode
(
RespCodeEnum
.
NO_AUTH_REQUEST
.
getCode
());
result
.
setErrorMsg
(
RespCodeEnum
.
NO_AUTH_REQUEST
.
getMsg
());
String
json
=
JSON
.
toJSONString
(
result
);
httpResponse
.
getWriter
().
print
(
json
);
return
false
;
}
}
return
executeLogin
(
request
,
response
);
}
/**
* 将非法请求返回401
*/
private
void
response401
(
ServletRequest
req
,
ServletResponse
resp
)
{
try
{
HttpServletResponse
response
=
(
HttpServletResponse
)
resp
;
response
.
setCharacterEncoding
(
"UTF-8"
);
response
.
setContentType
(
"application/json;charset=utf-8"
);
response
.
setStatus
(
401
);
response
.
getWriter
().
write
(
"{\"status\":401,\"message\":\"未登录!\"}"
);
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
e
.
getMessage
());
}
}
/**
* 将非法请求返回401
*/
private
void
response403
(
ServletRequest
req
,
ServletResponse
resp
)
{
try
{
HttpServletResponse
response
=
(
HttpServletResponse
)
resp
;
response
.
setCharacterEncoding
(
"UTF-8"
);
response
.
setContentType
(
"application/json;charset=utf-8"
);
response
.
setStatus
(
403
);
response
.
getWriter
().
write
(
"{\"status\":403,\"message\":Unauthorized!}"
);
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
e
.
getMessage
());
}
}
/**
* 获取请求头中的token
*/
private
String
getRequestToken
(
HttpServletRequest
httpRequest
)
{
//从header中获取token
return
httpRequest
.
getHeader
(
"Authorization"
);
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment