Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
D
data-server
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
data-server
Commits
71d94aa2
Commit
71d94aa2
authored
Mar 08, 2021
by
liqin
💬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bug fixed
parent
9c951d26
Expand all
Show 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
;
import
org.apache.shiro.authc.AuthenticationToken
;
/**
...
...
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shiro/ShiroConfig.java
View file @
71d94aa2
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.JwtFilter
;
import
org.apache.shiro.mgt.DefaultSessionStorageEvaluator
;
import
org.apache.shiro.mgt.DefaultSubjectDAO
;
import
org.apache.shiro.mgt.SecurityManager
;
import
org.apache.shiro.spring.LifecycleBeanPostProcessor
;
import
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
;
...
...
@@ -10,6 +12,7 @@ import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import
org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.DependsOn
;
import
javax.servlet.Filter
;
import
java.util.HashMap
;
...
...
@@ -18,6 +21,7 @@ import java.util.Map;
/**
* shiro配置类
*
* @author 86187
*/
@Configuration
...
...
@@ -48,7 +52,7 @@ public class ShiroConfig {
// 自定义的过滤器
Map
<
String
,
Filter
>
filterMap
=
new
HashMap
<>();
// map里面key值要为过滤器的名称,value为过滤器对象
filterMap
.
put
(
"oauth2"
,
new
Auth
Filter
());
filterMap
.
put
(
"oauth2"
,
new
Jwt
Filter
());
// 将自定义的过滤器加入到过滤器集合中
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
...
...
@@ -85,34 +89,44 @@ public class ShiroConfig {
return
new
LifecycleBeanPostProcessor
();
}
@Bean
public
static
DefaultAdvisorAutoProxyCreator
getDefaultAdvisorAutoProxyCreator
()
{
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
=
new
DefaultAdvisorAutoProxyCreator
();
defaultAdvisorAutoProxyCreator
.
setUsePrefix
(
true
);
return
defaultAdvisorAutoProxyCreator
;
@Bean
(
name
=
"authRealm"
)
@DependsOn
(
"lifecycleBeanPostProcessor"
)
public
AuthRealm
authRealm
()
{
return
new
AuthRealm
();
}
/**
* 配置加密匹配,使用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"
)
public
SecurityManager
securityManager
(
AuthRealm
authRealm
)
{
DefaultWebSecurityManager
securityManager
=
new
DefaultWebSecurityManager
();
securityManager
.
setRealm
(
authRealm
);
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
;
}
/**
* 开启Shiro的注解
*/
@Bean
@DependsOn
(
"lifecycleBeanPostProcessor"
)
public
static
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
()
{
DefaultAdvisorAutoProxyCreator
defaultAdvisorAutoProxyCreator
=
new
DefaultAdvisorAutoProxyCreator
();
defaultAdvisorAutoProxyCreator
.
setUsePrefix
(
true
);
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
defaultAdvisorAutoProxyCreator
.
setProxyTargetClass
(
true
);
return
defaultAdvisorAutoProxyCreator
;
}
@Bean
public
AuthorizationAttributeSourceAdvisor
authorizationAttributeSourceAdvisor
(
SecurityManager
securityManager
)
{
AuthorizationAttributeSourceAdvisor
advisor
=
new
AuthorizationAttributeSourceAdvisor
();
...
...
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"
);
}
}
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