set = new HashSet<>();
68 | //需要将 role 封装到 Set 作为 info.setRoles() 的参数
69 | set.add(role);
70 | //设置该用户拥有的角色
71 | info.setRoles(set);
72 | return info;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/shiroSimple/src/main/java/com/howie/shiro/config/ShiroConfig.java:
--------------------------------------------------------------------------------
1 | package com.howie.shiro.config;
2 |
3 | import com.howie.shiro.shiro.CustomRealm;
4 | import org.apache.shiro.mgt.SecurityManager;
5 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
6 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | import java.util.LinkedHashMap;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created with IntelliJ IDEA
15 | *
16 | * @Author yuanhaoyue swithaoy@gmail.com
17 | * @Description shiro 配置
18 | * @Date 2018-03-28
19 | * @Time 17:21
20 | */
21 | @Configuration
22 | public class ShiroConfig {
23 | /**
24 | * 过滤器默认权限表 {anon=anon, authc=authc, authcBasic=authcBasic, logout=logout,
25 | * noSessionCreation=noSessionCreation, perms=perms, port=port,
26 | * rest=rest, roles=roles, ssl=ssl, user=user}
27 | *
28 | * anon, authc, authcBasic, user 是第一组认证过滤器
29 | * perms, port, rest, roles, ssl 是第二组授权过滤器
30 | *
31 | * user 和 authc 的不同:当应用开启了rememberMe时, 用户下次访问时可以是一个user, 但绝不会是authc,
32 | * 因为authc是需要重新认证的, user表示用户不一定已通过认证, 只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe
33 | * 以前的一个用户登录时开启了rememberMe, 然后他关闭浏览器, 下次再访问时他就是一个user, 而不会authc
34 | *
35 | * @param securityManager 初始化 ShiroFilterFactoryBean 的时候需要注入 SecurityManager
36 | */
37 | @Bean
38 | public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
39 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
40 | // 必须设置 SecurityManager
41 | shiroFilterFactoryBean.setSecurityManager(securityManager);
42 | // setLoginUrl 如果不设置值,默认会自动寻找Web工程根目录下的"/login.jsp"页面 或 "/login" 映射
43 | shiroFilterFactoryBean.setLoginUrl("/notLogin");
44 | // 设置无权限时跳转的 url;
45 | shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
46 |
47 | // 设置拦截器
48 | Map filterChainDefinitionMap = new LinkedHashMap<>();
49 | //游客,开发权限
50 | filterChainDefinitionMap.put("/guest/**", "anon");
51 | //用户,需要角色权限 “user”
52 | filterChainDefinitionMap.put("/user/**", "roles[user]");
53 | //管理员,需要角色权限 “admin”
54 | filterChainDefinitionMap.put("/admin/**", "roles[admin]");
55 | //开放登陆接口
56 | filterChainDefinitionMap.put("/login", "anon");
57 | //其余接口一律拦截
58 | //主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截
59 | filterChainDefinitionMap.put("/**", "authc");
60 |
61 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
62 | System.out.println("Shiro拦截器工厂类注入成功");
63 | return shiroFilterFactoryBean;
64 | }
65 |
66 | /**
67 | * 注入 securityManager
68 | */
69 | @Bean
70 | public SecurityManager securityManager(CustomRealm customRealm) {
71 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
72 | // 设置realm.
73 | securityManager.setRealm(customRealm);
74 | return securityManager;
75 | }
76 | }
--------------------------------------------------------------------------------
/shiroJWT/src/main/java/com/howie/shirojwt/shiro/CustomRealm.java:
--------------------------------------------------------------------------------
1 | package com.howie.shirojwt.shiro;
2 |
3 | import com.howie.shirojwt.mapper.UserMapper;
4 | import com.howie.shirojwt.util.JWTUtil;
5 | import org.apache.shiro.authc.AuthenticationException;
6 | import org.apache.shiro.authc.AuthenticationInfo;
7 | import org.apache.shiro.authc.AuthenticationToken;
8 | import org.apache.shiro.authc.SimpleAuthenticationInfo;
9 | import org.apache.shiro.authz.AuthorizationInfo;
10 | import org.apache.shiro.authz.SimpleAuthorizationInfo;
11 | import org.apache.shiro.realm.AuthorizingRealm;
12 | import org.apache.shiro.subject.PrincipalCollection;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.stereotype.Component;
15 |
16 | import java.util.HashSet;
17 | import java.util.Set;
18 |
19 | /**
20 | * Created with IntelliJ IDEA
21 | *
22 | * @Author yuanhaoyue swithaoy@gmail.com
23 | * @Description 自定义 Realm
24 | * @Date 2018-04-09
25 | * @Time 16:58
26 | */
27 | @Component
28 | public class CustomRealm extends AuthorizingRealm {
29 | private final UserMapper userMapper;
30 |
31 | @Autowired
32 | public CustomRealm(UserMapper userMapper) {
33 | this.userMapper = userMapper;
34 | }
35 |
36 | /**
37 | * 必须重写此方法,不然会报错
38 | */
39 | @Override
40 | public boolean supports(AuthenticationToken token) {
41 | return token instanceof JWTToken;
42 | }
43 |
44 | /**
45 | * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
46 | */
47 | @Override
48 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
49 | System.out.println("————身份认证方法————");
50 | String token = (String) authenticationToken.getCredentials();
51 | // 解密获得username,用于和数据库进行对比
52 | String username = JWTUtil.getUsername(token);
53 | if (username == null || !JWTUtil.verify(token, username)) {
54 | throw new AuthenticationException("token认证失败!");
55 | }
56 | String password = userMapper.getPassword(username);
57 | if (password == null) {
58 | throw new AuthenticationException("该用户不存在!");
59 | }
60 | int ban = userMapper.checkUserBanStatus(username);
61 | if (ban == 1) {
62 | throw new AuthenticationException("该用户已被封号!");
63 | }
64 | return new SimpleAuthenticationInfo(token, token, "MyRealm");
65 | }
66 |
67 | /**
68 | * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
69 | */
70 | @Override
71 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
72 | System.out.println("————权限认证————");
73 | String username = JWTUtil.getUsername(principals.toString());
74 | SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
75 | //获得该用户角色
76 | String role = userMapper.getRole(username);
77 | //每个角色拥有默认的权限
78 | String rolePermission = userMapper.getRolePermission(username);
79 | //每个用户可以设置新的权限
80 | String permission = userMapper.getPermission(username);
81 | Set roleSet = new HashSet<>();
82 | Set permissionSet = new HashSet<>();
83 | //需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
84 | roleSet.add(role);
85 | permissionSet.add(rolePermission);
86 | permissionSet.add(permission);
87 | //设置该用户拥有的角色和权限
88 | info.setRoles(roleSet);
89 | info.setStringPermissions(permissionSet);
90 | return info;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/shiroJWT/src/main/java/com/howie/shirojwt/config/ShiroConfig.java:
--------------------------------------------------------------------------------
1 | package com.howie.shirojwt.config;
2 |
3 | import com.howie.shirojwt.filter.JWTFilter;
4 | import com.howie.shirojwt.shiro.CustomRealm;
5 | import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
6 | import org.apache.shiro.mgt.DefaultSubjectDAO;
7 | import org.apache.shiro.mgt.SecurityManager;
8 | import org.apache.shiro.spring.LifecycleBeanPostProcessor;
9 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
10 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
11 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
12 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
13 | import org.springframework.context.annotation.Bean;
14 | import org.springframework.context.annotation.Configuration;
15 |
16 | import javax.servlet.Filter;
17 | import java.util.HashMap;
18 | import java.util.Map;
19 |
20 | /**
21 | * Created with IntelliJ IDEA
22 | *
23 | * @Author yuanhaoyue swithaoy@gmail.com
24 | * @Description
25 | * @Date 2018-04-09
26 | * @Time 16:56
27 | */
28 | @Configuration
29 | public class ShiroConfig {
30 | /**
31 | * 先走 filter ,然后 filter 如果检测到请求头存在 token,则用 token 去 login,走 Realm 去验证
32 | */
33 | @Bean
34 | public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
35 | ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
36 |
37 | // 添加自己的过滤器并且取名为jwt
38 | Map filterMap = new LinkedHashMap<>();
39 | //设置我们自定义的JWT过滤器
40 | filterMap.put("jwt", new JWTFilter());
41 | factoryBean.setFilters(filterMap);
42 | factoryBean.setSecurityManager(securityManager);
43 | // 设置无权限时跳转的 url;
44 | factoryBean.setUnauthorizedUrl("/unauthorized/无权限");
45 | Map filterRuleMap = new HashMap<>();
46 | // 所有请求通过我们自己的JWT Filter
47 | filterRuleMap.put("/**", "jwt");
48 | // 访问 /unauthorized/** 不通过JWTFilter
49 | filterRuleMap.put("/unauthorized/**", "anon");
50 | factoryBean.setFilterChainDefinitionMap(filterRuleMap);
51 | return factoryBean;
52 | }
53 |
54 | /**
55 | * 注入 securityManager
56 | */
57 | @Bean
58 | public SecurityManager securityManager(CustomRealm customRealm) {
59 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
60 | // 设置自定义 realm.
61 | securityManager.setRealm(customRealm);
62 |
63 | /*
64 | * 关闭shiro自带的session,详情见文档
65 | * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
66 | */
67 | DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
68 | DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
69 | defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
70 | subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
71 | securityManager.setSubjectDAO(subjectDAO);
72 | return securityManager;
73 | }
74 |
75 | /**
76 | * 添加注解支持
77 | */
78 | @Bean
79 | public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
80 | DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
81 | // 强制使用cglib,防止重复代理和可能引起代理出错的问题
82 | // https://zhuanlan.zhihu.com/p/29161098
83 | defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
84 | return defaultAdvisorAutoProxyCreator;
85 | }
86 |
87 | @Bean
88 | public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
89 | AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
90 | advisor.setSecurityManager(securityManager);
91 | return advisor;
92 | }
93 |
94 | @Bean
95 | public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
96 | return new LifecycleBeanPostProcessor();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/shiroJWT/src/main/java/com/howie/shirojwt/filter/JWTFilter.java:
--------------------------------------------------------------------------------
1 | package com.howie.shirojwt.filter;
2 |
3 | import com.howie.shirojwt.shiro.JWTToken;
4 | import org.apache.shiro.authz.UnauthorizedException;
5 | import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.stereotype.Component;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 |
12 | import javax.servlet.ServletRequest;
13 | import javax.servlet.ServletResponse;
14 | import javax.servlet.http.HttpServletRequest;
15 | import javax.servlet.http.HttpServletResponse;
16 | import java.io.IOException;
17 | import java.net.URLEncoder;
18 |
19 | /**
20 | * Created with IntelliJ IDEA
21 | *
22 | * @Author yuanhaoyue swithaoy@gmail.com
23 | * @Description preHandle->isAccessAllowed->isLoginAttempt->executeLogin
24 | * @Date 2018-04-08
25 | * @Time 12:36
26 | */
27 | public class JWTFilter extends BasicHttpAuthenticationFilter {
28 | private Logger logger = LoggerFactory.getLogger(this.getClass());
29 |
30 | /**
31 | * 如果带有 token,则对 token 进行检查,否则直接通过
32 | */
33 | @Override
34 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
35 | //判断请求的请求头是否带上 "Token"
36 | if (isLoginAttempt(request, response)) {
37 | //如果存在,则进入 executeLogin 方法执行登入,检查 token 是否正确
38 | try {
39 | executeLogin(request, response);
40 | return true;
41 | } catch (Exception e) {
42 | //token 错误
43 | responseError(response, e.getMessage());
44 | }
45 | }
46 | //如果请求头不存在 Token,则可能是执行登陆操作或者是游客状态访问,无需检查 token,直接返回 true
47 | return true;
48 | }
49 |
50 | /**
51 | * 判断用户是否想要登入。
52 | * 检测 header 里面是否包含 Token 字段
53 | */
54 | @Override
55 | protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
56 | HttpServletRequest req = (HttpServletRequest) request;
57 | String token = req.getHeader("Token");
58 | return token != null;
59 | }
60 |
61 | /**
62 | * 执行登陆操作
63 | */
64 | @Override
65 | protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
66 | HttpServletRequest httpServletRequest = (HttpServletRequest) request;
67 | String token = httpServletRequest.getHeader("Token");
68 | JWTToken jwtToken = new JWTToken(token);
69 | // 提交给realm进行登入,如果错误他会抛出异常并被捕获
70 | getSubject(request, response).login(jwtToken);
71 | // 如果没有抛出异常则代表登入成功,返回true
72 | return true;
73 | }
74 |
75 | /**
76 | * 对跨域提供支持
77 | */
78 | @Override
79 | protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
80 | HttpServletRequest httpServletRequest = (HttpServletRequest) request;
81 | HttpServletResponse httpServletResponse = (HttpServletResponse) response;
82 | httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
83 | httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
84 | httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
85 | // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
86 | if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
87 | httpServletResponse.setStatus(HttpStatus.OK.value());
88 | return false;
89 | }
90 | return super.preHandle(request, response);
91 | }
92 |
93 | /**
94 | * 将非法请求跳转到 /unauthorized/**
95 | */
96 | private void responseError(ServletResponse response, String message) {
97 | try {
98 | HttpServletResponse httpServletResponse = (HttpServletResponse) response;
99 | //设置编码,否则中文字符在重定向时会变为空字符串
100 | message = URLEncoder.encode(message, "UTF-8");
101 | httpServletResponse.sendRedirect("/unauthorized/" + message);
102 | } catch (IOException e) {
103 | logger.error(e.getMessage());
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/shiroJWT/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/shiroSimple/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/shiroJWT/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/shiroSimple/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/shiro + springBoot 整合 JWT.md:
--------------------------------------------------------------------------------
1 |
2 | ## JWTUtil
3 | 我们利用 JWT 的工具类来生成我们的 token,这个工具类主要有生成 token 和 校验 token 两个方法
4 |
5 | 生成 token 时,指定 token 过期时间 ```EXPIRE_TIME``` 和签名密钥 ```SECRET```,然后将 date 和 username 写入 token 中,并使用带有密钥的 HS256 签名算法进行签名
6 | ```
7 | Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
8 | Algorithm algorithm = Algorithm.HMAC256(SECRET);
9 | JWT.create()
10 | .withClaim("username", username)
11 | //到期时间
12 | .withExpiresAt(date)
13 | //创建一个新的JWT,并使用给定的算法进行标记
14 | .sign(algorithm);
15 | ```
16 |
17 |
18 | ## 数据库表
19 | 
20 | role: 角色;permission: 权限;ban: 封号状态
21 | 
22 |
23 | 每个用户有对应的角色(user,admin),权限(normal,vip),而 user 角色默认权限为 normal, admin 角色默认权限为 vip(当然,user 也可以是 vip)
24 |
25 | ## 过滤器
26 | 在上一篇文章中,我们使用的是 shiro 默认的权限拦截 Filter,而因为 JWT 的整合,我们需要自定义自己的过滤器 JWTFilter,JWTFilter 继承了 BasicHttpAuthenticationFilter,并部分原方法进行了重写
27 |
28 | 该过滤器主要有三步:
29 | 1. 检验请求头是否带有 token ```((HttpServletRequest) request).getHeader("Token") != null```
30 | 2. 如果带有 token,执行 shiro 的 login() 方法,将 token 提交到 Realm 中进行检验;如果没有 token,说明当前状态为游客状态(或者其他一些不需要进行认证的接口)
31 | ```
32 | @Override
33 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
34 | //判断请求的请求头是否带上 "Token"
35 | if (((HttpServletRequest) request).getHeader("Token") != null) {
36 | //如果存在,则进入 executeLogin 方法执行登入,检查 token 是否正确
37 | try {
38 | executeLogin(request, response);
39 | return true;
40 | } catch (Exception e) {
41 | //token 错误
42 | responseError(response, e.getMessage());
43 | }
44 | }
45 | //如果请求头不存在 Token,则可能是执行登陆操作或者是游客状态访问,无需检查 token,直接返回 true
46 | return true;
47 | }
48 |
49 | @Override
50 | protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
51 | HttpServletRequest httpServletRequest = (HttpServletRequest) request;
52 | String token = httpServletRequest.getHeader("Token");
53 | JWTToken jwtToken = new JWTToken(token);
54 | // 提交给realm进行登入,如果错误他会抛出异常并被捕获
55 | getSubject(request, response).login(jwtToken);
56 | // 如果没有抛出异常则代表登入成功,返回true
57 | return true;
58 | }
59 | ```
60 | 3. 如果在 token 校验的过程中出现错误,如 token 校验失败,那么我会将该请求视为认证不通过,则重定向到 ```/unauthorized/**```
61 |
62 |
63 | 另外,我将跨域支持放到了该过滤器来处理
64 |
65 | ## Realm 类
66 | 依然是我们的自定义 Realm ,对这一块还不了解的可以先看我的上一篇 shiro 的文章
67 | - 身份认证
68 | ```
69 | if (username == null || !JWTUtil.verify(token, username)) {
70 | throw new AuthenticationException("token认证失败!");
71 | }
72 | String password = userMapper.getPassword(username);
73 | if (password == null) {
74 | throw new AuthenticationException("该用户不存在!");
75 | }
76 | int ban = userMapper.checkUserBanStatus(username);
77 | if (ban == 1) {
78 | throw new AuthenticationException("该用户已被封号!");
79 | }
80 | ```
81 | 拿到传来的 token ,检查 token 是否有效,用户是否存在,以及用户的封号情况
82 |
83 | - 权限认证
84 | ```
85 | SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
86 | //获得该用户角色
87 | String role = userMapper.getRole(username);
88 | //每个角色拥有默认的权限
89 | String rolePermission = userMapper.getRolePermission(username);
90 | //每个用户可以设置新的权限
91 | String permission = userMapper.getPermission(username);
92 | Set roleSet = new HashSet<>();
93 | Set permissionSet = new HashSet<>();
94 | //需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
95 | roleSet.add(role);
96 | permissionSet.add(rolePermission);
97 | permissionSet.add(permission);
98 | //设置该用户拥有的角色和权限
99 | info.setRoles(roleSet);
100 | info.setStringPermissions(permissionSet);
101 | ```
102 | 利用 token 中获得的 username,分别从数据库查到该用户所拥有的角色,权限,存入 SimpleAuthorizationInfo 中
103 |
104 | ## ShiroConfig 配置类
105 | 设置好我们自定义的 filter,并使所有请求通过我们的过滤器,除了我们用于处理未认证请求的 ```/unauthorized/**```
106 | ```
107 | @Bean
108 | public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
109 | ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
110 |
111 | // 添加自己的过滤器并且取名为jwt
112 | Map filterMap = new HashMap<>();
113 | //设置我们自定义的JWT过滤器
114 | filterMap.put("jwt", new JWTFilter());
115 | factoryBean.setFilters(filterMap);
116 | factoryBean.setSecurityManager(securityManager);
117 | Map filterRuleMap = new HashMap<>();
118 | // 所有请求通过我们自己的JWT Filter
119 | filterRuleMap.put("/**", "jwt");
120 | // 访问 /unauthorized/** 不通过JWTFilter
121 | filterRuleMap.put("/unauthorized/**", "anon");
122 | factoryBean.setFilterChainDefinitionMap(filterRuleMap);
123 | return factoryBean;
124 | }
125 | ```
126 | ## 权限控制注解 @RequiresRoles, @RequiresPermissions
127 | 这两个注解为我们主要的权限控制注解, 如
128 | ```
129 | // 拥有 admin 角色可以访问
130 | @RequiresRoles("admin")
131 | ```
132 | ```
133 | // 拥有 user 或 admin 角色可以访问
134 | @RequiresRoles(logical = Logical.OR, value = {"user", "admin"})
135 | ```
136 | ```
137 | // 拥有 vip 和 normal 权限可以访问
138 | @RequiresPermissions(logical = Logical.AND, value = {"vip", "normal"})
139 | ```
140 | ```
141 | // 拥有 user 或 admin 角色,且拥有 vip 权限可以访问
142 | @GetMapping("/getVipMessage")
143 | @RequiresRoles(logical = Logical.OR, value = {"user", "admin"})
144 | @RequiresPermissions("vip")
145 | public ResultMap getVipMessage() {
146 | return resultMap.success().code(200).message("成功获得 vip 信息!");
147 | }
148 | ```
149 | 当我们写的接口拥有以上的注解时,如果请求没有带有 token 或者带了 token 但权限认证不通过,则会报 UnauthenticatedException 异常,但是我在 ExceptionController 类对这些异常进行了集中处理
150 | ```
151 | @ExceptionHandler(ShiroException.class)
152 | public ResultMap handle401() {
153 | return resultMap.fail().code(401).message("您没有权限访问!");
154 | }
155 | ```
156 | 这时,出现 shiro 相关的异常时则会返回
157 | ```
158 | {
159 | "result": "fail",
160 | "code": 401,
161 | "message": "您没有权限访问!"
162 | }
163 | ```
164 | 除了以上两种,还有 @RequiresAuthentication ,@RequiresUser 等注解
165 |
166 | ## 功能实现
167 | 用户角色分为三类,管理员 admin,普通用户 user,游客 guest;admin 默认权限为 vip,user 默认权限为 normal,当 user 升级为 vip 权限时可以访问 vip 权限的页面。
168 |
169 | 具体实现可以看源代码(开头已经给出地址)
170 |
171 | ### 登陆
172 | 登陆接口不带有 token,当登陆密码,用户名验证正确后返回 token。
173 | ```
174 | @PostMapping("/login")
175 | public ResultMap login(@RequestParam("username") String username,
176 | @RequestParam("password") String password) {
177 | String realPassword = userMapper.getPassword(username);
178 | if (realPassword == null) {
179 | return resultMap.fail().code(401).message("用户名错误");
180 | } else if (!realPassword.equals(password)) {
181 | return resultMap.fail().code(401).message("密码错误");
182 | } else {
183 | return resultMap.success().code(200).message(JWTUtil.createToken(username));
184 | }
185 | }
186 | ```
187 | ```
188 | {
189 | "result": "success",
190 | "code": 200,
191 | "message": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MjUxODQyMzUsInVzZXJuYW1lIjoiaG93aWUifQ.fG5Qs739Hxy_JjTdSIx_iiwaBD43aKFQMchx9fjaCRo"
192 | }
193 | ```
194 |
195 | ## 异常处理
196 | ```
197 | // 捕捉shiro的异常
198 | @ExceptionHandler(ShiroException.class)
199 | public ResultMap handle401() {
200 | return resultMap.fail().code(401).message("您没有权限访问!");
201 | }
202 |
203 | // 捕捉其他所有异常
204 | @ExceptionHandler(Exception.class)
205 | public ResultMap globalException(HttpServletRequest request, Throwable ex) {
206 | return resultMap.fail()
207 | .code(getStatus(request).value())
208 | .message("访问出错,无法访问: " + ex.getMessage());
209 | }
210 | ```
211 |
212 | ## 权限控制
213 | - UserController(user 或 admin 可以访问)
214 | 在接口上带上 ```@RequiresRoles(logical = Logical.OR, value = {"user", "admin"})```
215 | - vip 权限
216 | 再加上```@RequiresPermissions("vip")```
217 |
218 | - AdminController(admin 可以访问)
219 | 在接口上带上 ```@RequiresRoles("admin")```
220 |
221 | - GuestController(所有人可以访问)
222 | 不做权限处理
223 |
224 | ## 测试结果
225 | 
226 | 
227 | 
228 | 
229 | 
230 | 
231 |
232 |
--------------------------------------------------------------------------------
/shiro 整合 springBoot 实现基本的角色权限控制.md:
--------------------------------------------------------------------------------
1 | ## 依赖包
2 |
3 | ```
4 |
5 | org.apache.shiro
6 | shiro-spring
7 | 1.3.2
8 |
9 | ```
10 | ## 数据库表
11 | 一切从简,用户 user 表,以及角色 role 表
12 | 
13 |
14 | 
15 |
16 |
17 | ## Shiro 相关类
18 | ### Shiro 配置类
19 | ```
20 | @Configuration
21 | public class ShiroConfig {
22 | @Bean
23 | public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
24 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
25 | // 必须设置 SecurityManager
26 | shiroFilterFactoryBean.setSecurityManager(securityManager);
27 | // setLoginUrl 如果不设置值,默认会自动寻找Web工程根目录下的"/login.jsp"页面 或 "/login" 映射
28 | shiroFilterFactoryBean.setLoginUrl("/notLogin");
29 | // 设置无权限时跳转的 url;
30 | shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
31 |
32 | // 设置拦截器
33 | Map filterChainDefinitionMap = new LinkedHashMap<>();
34 | //游客,开发权限
35 | filterChainDefinitionMap.put("/guest/**", "anon");
36 | //用户,需要角色权限 “user”
37 | filterChainDefinitionMap.put("/user/**", "roles[user]");
38 | //管理员,需要角色权限 “admin”
39 | filterChainDefinitionMap.put("/admin/**", "roles[admin]");
40 | //开放登陆接口
41 | filterChainDefinitionMap.put("/login", "anon");
42 | //其余接口一律拦截
43 | //主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截
44 | filterChainDefinitionMap.put("/**", "authc");
45 |
46 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
47 | System.out.println("Shiro拦截器工厂类注入成功");
48 | return shiroFilterFactoryBean;
49 | }
50 |
51 | /**
52 | * 注入 securityManager
53 | */
54 | @Bean
55 | public SecurityManager securityManager() {
56 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
57 | // 设置realm.
58 | securityManager.setRealm(customRealm());
59 | return securityManager;
60 | }
61 |
62 | /**
63 | * 自定义身份认证 realm;
64 | *
65 | * 必须写这个类,并加上 @Bean 注解,目的是注入 CustomRealm,
66 | * 否则会影响 CustomRealm类 中其他类的依赖注入
67 | */
68 | @Bean
69 | public CustomRealm customRealm() {
70 | return new CustomRealm();
71 | }
72 | }
73 | ```
74 | **注意**:里面的 SecurityManager 类导入的应该是 ```import org.apache.shiro.mgt.SecurityManager;``` 但是,如果你是复制代码过来的话,会默认导入 ```java.lang.SecurityManager``` 这里也稍稍有点坑,其他的类的话,也是都属于 shiro 包里面的类
75 |
76 | shirFilter 方法中主要是设置了一些重要的跳转 url,比如未登陆时,无权限时的跳转;以及设置了各类 url 的权限拦截,比如 /user 开始的 url 需要 user 权限,/admin 开始的 url 需要 admin 权限等
77 |
78 | #### 权限拦截 Filter
79 |
80 | 当运行一个Web应用程序时,Shiro将会创建一些有用的默认 Filter 实例,并自动地将它们置为可用,而这些默认的 Filter 实例是被 DefaultFilter 枚举类定义的,当然我们也可以自定义 Filter 实例,这些在以后的文章中会讲到
81 | 
82 |
83 | Filter | 解释
84 | ---|---
85 | anon | 无参,开放权限,可以理解为匿名用户或游客
86 | authc | 无参,需要认证
87 | logout | 无参,注销,执行后会直接跳转到``` shiroFilterFactoryBean.setLoginUrl(); ``` 设置的 url
88 | authcBasic | 无参,表示 httpBasic 认证
89 | user | 无参,表示必须存在用户,当登入操作时不做检查
90 | ssl | 无参,表示安全的URL请求,协议为 https
91 | perms[user] | 参数可写多个,表示需要某个或某些权限才能通过,多个参数时写 perms["user, admin"],当有多个参数时必须每个参数都通过才算通过
92 | roles[admin] | 参数可写多个,表示是某个或某些角色才能通过,多个参数时写 roles["admin,user"],当有多个参数时必须每个参数都通过才算通过
93 | rest[user] |根据请求的方法,相当于 perms[user:method],其中 method 为 post,get,delete 等
94 | port[8081] | 当请求的URL端口不是8081时,跳转到schemal://serverName:8081?queryString 其中 schmal 是协议 http 或 https 等等,serverName 是你访问的 Host,8081 是 Port 端口,queryString 是你访问的 URL 里的 ? 后面的参数
95 |
96 | 常用的主要就是 anon,authc,user,roles,perms 等
97 |
98 | **注意**:anon, authc, authcBasic, user 是第一组认证过滤器,perms, port, rest, roles, ssl 是第二组授权过滤器,要通过授权过滤器,就先要完成登陆认证操作(即先要完成认证才能前去寻找授权) 才能走第二组授权器(例如访问需要 roles 权限的 url,如果还没有登陆的话,会直接跳转到 ``` shiroFilterFactoryBean.setLoginUrl(); ``` 设置的 url )
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | ### 自定义 realm 类
108 | 我们首先要继承 AuthorizingRealm 类来自定义我们自己的 realm 以进行我们自定义的身份,权限认证操作。
109 | 记得要 Override 重写 doGetAuthenticationInfo 和 doGetAuthorizationInfo 两个方法(两个方法名很相似,不要搞错)
110 | ```
111 | public class CustomRealm extends AuthorizingRealm {
112 | private UserMapper userMapper;
113 |
114 | @Autowired
115 | private void setUserMapper(UserMapper userMapper) {
116 | this.userMapper = userMapper;
117 | }
118 |
119 | /**
120 | * 获取身份验证信息
121 | * Shiro中,最终是通过 Realm 来获取应用程序中的用户、角色及权限信息的。
122 | *
123 | * @param authenticationToken 用户身份信息 token
124 | * @return 返回封装了用户信息的 AuthenticationInfo 实例
125 | */
126 | @Override
127 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
128 | System.out.println("————身份认证方法————");
129 | UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
130 | // 从数据库获取对应用户名密码的用户
131 | String password = userMapper.getPassword(token.getUsername());
132 | if (null == password) {
133 | throw new AccountException("用户名不正确");
134 | } else if (!password.equals(new String((char[]) token.getCredentials()))) {
135 | throw new AccountException("密码不正确");
136 | }
137 | return new SimpleAuthenticationInfo(token.getPrincipal(), password, getName());
138 | }
139 |
140 | /**
141 | * 获取授权信息
142 | *
143 | * @param principalCollection
144 | * @return
145 | */
146 | @Override
147 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
148 | System.out.println("————权限认证————");
149 | String username = (String) SecurityUtils.getSubject().getPrincipal();
150 | SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
151 | //获得该用户角色
152 | String role = userMapper.getRole(username);
153 | Set set = new HashSet<>();
154 | //需要将 role 封装到 Set 作为 info.setRoles() 的参数
155 | set.add(role);
156 | //设置该用户拥有的角色
157 | info.setRoles(set);
158 | return info;
159 | }
160 | }
161 | ```
162 | 重写的两个方法分别是实现身份认证以及权限认证,shiro 中有个作登陆操作的 ``` Subject.login() ``` 方法,当我们把封装了用户名,密码的 token 作为参数传入,便会跑进这两个方法里面(不一定两个方法都会进入)
163 |
164 | 其中 doGetAuthorizationInfo 方法只有在需要权限认证时才会进去,比如前面配置类中配置了 ``` filterChainDefinitionMap.put("/admin/**", "roles[admin]");``` 的管理员角色,这时进入 /admin 时就会进入 doGetAuthorizationInfo 方法来检查权限;而 doGetAuthenticationInfo 方法则是需要身份认证时(比如前面的 ```Subject.login()``` 方法)才会进入
165 |
166 | 再说下 UsernamePasswordToken 类,我们可以从该对象拿到登陆时的用户名和密码(登陆时会使用 ```new UsernamePasswordToken(username, password);```),而 get 用户名或密码有以下几个方法
167 | ```
168 | token.getUsername() //获得用户名 String
169 | token.getPrincipal() //获得用户名 Object
170 | token.getPassword() //获得密码 char[]
171 | token.getCredentials() //获得密码 Object
172 | ```
173 |
174 | **注意**:有很多人会发现,UserMapper 等类,接口无法通过 @Autowired 注入进来,跑程序的时候会报 NullPointerException,网上说了很多诸如是 Spring 加载顺序等原因,但其实有一个很重要的地方要大家注意,CustomRealm 这个类是在 shiro 配置类的 ```securityManager.setRealm() ``` 方法中设置进去的,而很多人直接写```securityManager.setRealm(new CustomRealm());``` ,这样是不行的,必须要使用 @Bean 注入 MyRealm,不能直接 new 对象:
175 | ```
176 | @Bean
177 | public SecurityManager securityManager() {
178 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
179 | // 设置realm.
180 | securityManager.setRealm(customRealm());
181 | return securityManager;
182 | }
183 |
184 | @Bean
185 | public CustomRealm customRealm() {
186 | return new CustomRealm();
187 | }
188 | ```
189 | 道理也很简单,和 Controller 中调用 Service 一样,都是 SpringBean,不能自己 new
190 |
191 | 当然,同样的道理也可以这样写:
192 | ```
193 | @Bean
194 | public SecurityManager securityManager(CustomRealm customRealm) {
195 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
196 | // 设置realm.
197 | securityManager.setRealm(customRealm);
198 | return securityManager;
199 | }
200 | ```
201 | 然后只要在 CustomRealm 类加上个类似 @Component 的注解即可
202 |
203 | ## 功能实现
204 | 本文的功能全部以接口返回 json 数据的方式实现
205 | ### 根据 url 权限分配 controller
206 | ```
207 | 游客
208 | @RestController
209 | @RequestMapping("/guest")
210 | public class GuestController{
211 | @Autowired
212 | private final ResultMap resultMap;
213 |
214 | @RequestMapping(value = "/enter", method = RequestMethod.GET)
215 | public ResultMap login() {
216 | return resultMap.success().message("欢迎进入,您的身份是游客");
217 | }
218 |
219 | @RequestMapping(value = "/getMessage", method = RequestMethod.GET)
220 | public ResultMap submitLogin() {
221 | return resultMap.success().message("您拥有获得该接口的信息的权限!");
222 | }
223 | }
224 | ```
225 | ```
226 | 普通登陆用户
227 | @RestController
228 | @RequestMapping("/user")
229 | public class UserController{
230 | @Autowired
231 | private final ResultMap resultMap;
232 |
233 | @RequestMapping(value = "/getMessage", method = RequestMethod.GET)
234 | public ResultMap getMessage() {
235 | return resultMap.success().message("您拥有用户权限,可以获得该接口的信息!");
236 | }
237 | }
238 | ```
239 | ```
240 | 管理员
241 | @RestController
242 | @RequestMapping("/admin")
243 | public class AdminController {
244 | @Autowired
245 | private final ResultMap resultMap;
246 |
247 | @RequestMapping(value = "/getMessage", method = RequestMethod.GET)
248 | public ResultMap getMessage() {
249 | return resultMap.success().message("您拥有管理员权限,可以获得该接口的信息!");
250 | }
251 | }
252 | ```
253 | 突然注意到 CustomRealm 类那里抛出了 AccountException 异常,现在建个类进行异常捕获
254 | ```
255 | @RestControllerAdvice
256 | public class ExceptionController {
257 | private final ResultMap resultMap;
258 |
259 | @Autowired
260 | public ExceptionController(ResultMap resultMap) {
261 | this.resultMap = resultMap;
262 | }
263 |
264 | // 捕捉 CustomRealm 抛出的异常
265 | @ExceptionHandler(AccountException.class)
266 | public ResultMap handleShiroException(Exception ex) {
267 | return resultMap.fail().message(ex.getMessage());
268 | }
269 | }
270 | ```
271 | 还有进行登陆等处理的 LoginController
272 | ```
273 | @RestController
274 | public class LoginController {
275 | @Autowired
276 | private ResultMap resultMap;
277 | private UserMapper userMapper;
278 |
279 | @RequestMapping(value = "/notLogin", method = RequestMethod.GET)
280 | public ResultMap notLogin() {
281 | return resultMap.success().message("您尚未登陆!");
282 | }
283 |
284 | @RequestMapping(value = "/notRole", method = RequestMethod.GET)
285 | public ResultMap notRole() {
286 | return resultMap.success().message("您没有权限!");
287 | }
288 |
289 | @RequestMapping(value = "/logout", method = RequestMethod.GET)
290 | public ResultMap logout() {
291 | Subject subject = SecurityUtils.getSubject();
292 | //注销
293 | subject.logout();
294 | return resultMap.success().message("成功注销!");
295 | }
296 |
297 | /**
298 | * 登陆
299 | *
300 | * @param username 用户名
301 | * @param password 密码
302 | */
303 | @RequestMapping(value = "/login", method = RequestMethod.POST)
304 | public ResultMap login(String username, String password) {
305 | // 从SecurityUtils里边创建一个 subject
306 | Subject subject = SecurityUtils.getSubject();
307 | // 在认证提交前准备 token(令牌)
308 | UsernamePasswordToken token = new UsernamePasswordToken(username, password);
309 | // 执行认证登陆
310 | subject.login(token);
311 | //根据权限,指定返回数据
312 | String role = userMapper.getRole(username);
313 | if ("user".equals(role)) {
314 | return resultMap.success().message("欢迎登陆");
315 | }
316 | if ("admin".equals(role)) {
317 | return resultMap.success().message("欢迎来到管理员页面");
318 | }
319 | return resultMap.fail().message("权限错误!");
320 | }
321 | }
322 | ```
323 | ### 测试
324 | 
325 |
326 |
327 | 
328 |
329 | 
330 |
331 | 
332 |
333 | 
334 |
335 | 
336 |
337 | 
338 |
--------------------------------------------------------------------------------