|
17 | 17 |
|
18 | 18 | package org.hswebframework.web.controller.authorization;
|
19 | 19 |
|
20 |
| -import org.apache.commons.codec.binary.Base64; |
21 |
| -import org.hswebframework.expands.security.Encrypt; |
22 |
| -import org.hswebframework.expands.security.rsa.RSAEncrypt; |
23 |
| -import org.hswebframework.expands.security.rsa.RSAPrivateEncrypt; |
| 20 | +import io.swagger.annotations.Api; |
| 21 | +import io.swagger.annotations.ApiOperation; |
| 22 | +import io.swagger.annotations.ApiParam; |
24 | 23 | import org.hswebframework.web.BusinessException;
|
25 | 24 | import org.hswebframework.web.NotFoundException;
|
26 | 25 | import org.hswebframework.web.authorization.Authorization;
|
27 |
| -import org.hswebframework.web.authorization.listener.UserAuthorizationConfigRegister; |
28 |
| -import org.hswebframework.web.authorization.listener.UserAuthorizationListener; |
| 26 | +import org.hswebframework.web.authorization.annotation.Authorize; |
| 27 | +import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher; |
| 28 | +import org.hswebframework.web.authorization.listener.event.*; |
29 | 29 | import org.hswebframework.web.controller.message.ResponseMessage;
|
30 | 30 | import org.hswebframework.web.entity.authorization.UserEntity;
|
31 | 31 | import org.hswebframework.web.logging.AccessLogger;
|
32 |
| -import org.hswebframework.web.service.AbstractService; |
33 | 32 | import org.hswebframework.web.service.authorization.UserService;
|
34 |
| -import org.hswebframework.web.service.authorization.VerifyCode; |
35 |
| -import org.hswebframework.web.service.authorization.VerifyCodeGenerator; |
36 | 33 | import org.springframework.beans.factory.annotation.Autowired;
|
37 |
| -import org.springframework.beans.factory.annotation.Value; |
38 |
| -import org.springframework.http.MediaType; |
39 | 34 | import org.springframework.web.bind.annotation.*;
|
40 | 35 |
|
41 |
| -import javax.servlet.http.HttpServletResponse; |
42 |
| -import javax.servlet.http.HttpSession; |
43 |
| -import java.io.IOException; |
44 |
| -import java.util.List; |
| 36 | +import javax.servlet.http.HttpServletRequest; |
| 37 | +import java.util.function.Function; |
45 | 38 |
|
46 | 39 | import static org.hswebframework.web.controller.message.ResponseMessage.ok;
|
47 | 40 |
|
|
53 | 46 | @RestController
|
54 | 47 | @RequestMapping("${hsweb.web.mappings.authorize:authorize}")
|
55 | 48 | @AccessLogger("授权")
|
| 49 | +@Api(tags = "authorize-simple", description = "提供基本的授权功能") |
56 | 50 | public class AuthorizationController {
|
57 | 51 |
|
58 |
| - private static final String RSA_PRIVATE_KEY_NAME = "RSA_PRIVATE_KEY"; |
59 |
| - private static final String VERIFY_CODE_NAME = "VERIFY_CODE"; |
60 |
| - private static final String NEED_VERIFY_CODE_NAME = "NEED_VERIFY_CODE"; |
61 |
| - |
62 |
| - @Autowired(required = false) |
63 |
| - private VerifyCodeGenerator verifyCodeGenerator; |
| 52 | +// private static final String RSA_PRIVATE_KEY_NAME = "RSA_PRIVATE_KEY"; |
| 53 | +// private static final String VERIFY_CODE_NAME = "VERIFY_CODE"; |
64 | 54 |
|
65 | 55 | @Autowired
|
66 | 56 | private UserService userService;
|
67 | 57 |
|
68 |
| - @Autowired(required = false) |
69 |
| - private List<UserAuthorizationListener> userAuthorizationListeners; |
70 |
| - |
71 |
| - @Value("${hsweb.web.authorize.rsa:false}") |
72 |
| - private boolean useRsa = false; |
73 |
| - |
74 |
| - private UserAuthorizationListenerAdapter listenerAdapter = new UserAuthorizationListenerAdapter(); |
75 |
| - |
76 |
| - @GetMapping(value = "/public-key") |
77 |
| - @AccessLogger("获取公钥") |
78 |
| - public ResponseMessage getAuthorizeToken(HttpSession session) { |
79 |
| - RSAEncrypt rsaEncrypt = Encrypt.rsa(); |
80 |
| - String publicKey = rsaEncrypt.publicEncrypt().getKey(); |
81 |
| - String privateKey = rsaEncrypt.privateEncrypt().getKey(); |
82 |
| - session.setAttribute(RSA_PRIVATE_KEY_NAME, privateKey); |
83 |
| - return ok(publicKey); |
84 |
| - } |
85 |
| - |
86 |
| - @GetMapping(value = "/verify-code") |
87 |
| - @AccessLogger("获取验证码") |
88 |
| - public void getVerifyCode(HttpServletResponse response, HttpSession session) throws IOException { |
89 |
| - if (verifyCodeGenerator == null) throw new NotFoundException("{verify_code_not_found}"); |
90 |
| - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); |
91 |
| - response.setHeader("Content-disposition", "attachment;filename=verify-code.png"); |
92 |
| - VerifyCode verifyCode = verifyCodeGenerator.generate(); |
93 |
| - session.setAttribute(RSA_PRIVATE_KEY_NAME, verifyCode.getCode()); |
94 |
| - verifyCode.write(response.getOutputStream()); |
95 |
| - } |
96 |
| - |
97 |
| - @RequestMapping("/login-out") |
| 58 | + @Autowired |
| 59 | + private AuthorizationListenerDispatcher authorizationListenerDispatcher; |
| 60 | + |
| 61 | +// @GetMapping(value = "/public-key") |
| 62 | +// @AccessLogger("获取公钥") |
| 63 | +// @ApiOperation("获取rsa公钥,当开启了用户名密码加密的时候使用此接口获取用于加密的公钥") |
| 64 | +// public ResponseMessage getAuthorizeToken(@ApiParam(hidden = true) HttpSession session) { |
| 65 | +// RSAEncrypt rsaEncrypt = Encrypt.rsa(); |
| 66 | +// String publicKey = rsaEncrypt.publicEncrypt().getKey(); |
| 67 | +// String privateKey = rsaEncrypt.privateEncrypt().getKey(); |
| 68 | +// session.setAttribute(RSA_PRIVATE_KEY_NAME, privateKey); |
| 69 | +// return ok(publicKey); |
| 70 | +// } |
| 71 | + |
| 72 | + @GetMapping("/login-out") |
98 | 73 | @AccessLogger("退出登录")
|
99 |
| - public ResponseMessage loginOut(Authorization authorization) { |
100 |
| - listenerAdapter.onLoginOut(authorization); |
| 74 | + @Authorize |
| 75 | + @ApiOperation("退出当前登录") |
| 76 | + public ResponseMessage exit(@ApiParam(hidden = true) Authorization authorization) { |
| 77 | + authorizationListenerDispatcher.doEvent(new AuthorizationExitEvent(authorization)); |
101 | 78 | return ok();
|
102 | 79 | }
|
103 | 80 |
|
104 | 81 | @PostMapping(value = "/login")
|
105 | 82 | @AccessLogger("授权")
|
106 |
| - public ResponseMessage authorize(@RequestParam String username, |
107 |
| - @RequestParam String password, |
108 |
| - String verifyCode, |
109 |
| - @RequestParam(defaultValue = "false") boolean remember, |
110 |
| - HttpSession session) { |
| 83 | + @ApiOperation("用户名密码登录") |
| 84 | + public ResponseMessage<String> authorize(@RequestParam @ApiParam("用户名") String username, |
| 85 | + @RequestParam @ApiParam("密码") String password, |
| 86 | + @ApiParam(hidden = true) HttpServletRequest request) { |
| 87 | + |
| 88 | + AuthorizationFailedEvent.Reason reason = AuthorizationFailedEvent.Reason.OTHER; |
| 89 | + Function<String, Object> parameterGetter = request::getParameter; |
111 | 90 | try {
|
112 |
| - if (useRsa) { |
113 |
| - String privateKey = (String) session.getAttribute(RSA_PRIVATE_KEY_NAME); |
114 |
| - if (privateKey == null) throw new BusinessException("{private_key_is_null}"); |
115 |
| - // 解密用户名密码 |
116 |
| - try { |
117 |
| - RSAEncrypt rsaEncrypt = Encrypt.rsa(); |
118 |
| - RSAPrivateEncrypt rsaPrivateEncrypt = rsaEncrypt.privateEncrypt(privateKey); |
119 |
| - byte[] username_data = Base64.decodeBase64(username); |
120 |
| - byte[] password_data = Base64.decodeBase64(password); |
121 |
| - username = new String(rsaPrivateEncrypt.decrypt(username_data)); |
122 |
| - password = new String(rsaPrivateEncrypt.decrypt(password_data)); |
123 |
| - } catch (Exception e) { |
124 |
| - throw new BusinessException("{decrypt_param_error}", e, 400); |
125 |
| - } |
126 |
| - } |
127 |
| - UserAuthorizationConfigRegister configHolder = (useVerify) -> session.setAttribute(NEED_VERIFY_CODE_NAME, useVerify); |
128 |
| - listenerAdapter.onConfig(username, configHolder); |
129 |
| - Object useVerifyCode = session.getAttribute(NEED_VERIFY_CODE_NAME); |
130 |
| - // 尝试使用验证码验证 |
131 |
| - if (useVerifyCode instanceof Boolean && (Boolean) useVerifyCode) { |
132 |
| - String realVerifyCode = (String) session.getAttribute(VERIFY_CODE_NAME); |
133 |
| - if (realVerifyCode == null || !realVerifyCode.equalsIgnoreCase(verifyCode)) { |
134 |
| - throw new BusinessException("{verify_code_error}"); |
135 |
| - } |
136 |
| - } |
137 |
| - listenerAdapter.onAuthorizeBefore(username); |
| 91 | + AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username, password, parameterGetter); |
| 92 | + authorizationListenerDispatcher.doEvent(decodeEvent); |
| 93 | + username = decodeEvent.getUsername(); |
| 94 | + password = decodeEvent.getPassword(); |
| 95 | + |
| 96 | + AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter); |
| 97 | + authorizationListenerDispatcher.doEvent(beforeEvent); |
| 98 | + |
| 99 | +// if (useRsa) { |
| 100 | +// String privateKey = (String) session.getAttribute(RSA_PRIVATE_KEY_NAME); |
| 101 | +// if (privateKey == null) throw new BusinessException("{private_key_is_null}"); |
| 102 | +// // 解密用户名密码 |
| 103 | +// try { |
| 104 | +// RSAEncrypt rsaEncrypt = Encrypt.rsa(); |
| 105 | +// RSAPrivateEncrypt rsaPrivateEncrypt = rsaEncrypt.privateEncrypt(privateKey); |
| 106 | +// byte[] username_data = Base64.decodeBase64(username); |
| 107 | +// byte[] password_data = Base64.decodeBase64(password); |
| 108 | +// username = new String(rsaPrivateEncrypt.decrypt(username_data)); |
| 109 | +// password = new String(rsaPrivateEncrypt.decrypt(password_data)); |
| 110 | +// } catch (Exception e) { |
| 111 | +// throw new BusinessException("{decrypt_param_error}", e, 400); |
| 112 | +// } |
| 113 | +// } |
| 114 | + |
| 115 | +// UserAuthorizationConfigRegister configHolder = (useVerify) -> session.setAttribute(NEED_VERIFY_CODE_NAME, useVerify); |
| 116 | +// listenerAdapter.onConfig(username, configHolder); |
| 117 | +// Object useVerifyCode = session.getAttribute(NEED_VERIFY_CODE_NAME); |
| 118 | +// // 尝试使用验证码验证 |
| 119 | +// if (Boolean.TRUE.equals(useVerifyCode)) { |
| 120 | +// String realVerifyCode = (String) session.getAttribute(VERIFY_CODE_NAME); |
| 121 | +// if (realVerifyCode == null || !realVerifyCode.equalsIgnoreCase(verifyCode)) { |
| 122 | +// throw new BusinessException("{verify_code_error}"); |
| 123 | +// } |
| 124 | +// } |
| 125 | +// listenerAdapter.onAuthorizeBefore(username); |
138 | 126 | UserEntity entity = userService.selectByUsername(username);
|
139 |
| - AbstractService.assertNotNull(entity, "{user_not_exists}"); |
140 |
| - if (!entity.isEnabled()) { |
| 127 | + if (entity == null) { |
| 128 | + reason = AuthorizationFailedEvent.Reason.USER_NOT_EXISTS; |
| 129 | + throw new NotFoundException("{user_not_exists}"); |
| 130 | + } |
| 131 | + if (Boolean.FALSE.equals(entity.isEnabled())) { |
| 132 | + reason = AuthorizationFailedEvent.Reason.USER_DISABLED; |
141 | 133 | throw new BusinessException("{user_is_disabled}", 400);
|
142 | 134 | }
|
143 | 135 | password = userService.encodePassword(password, entity.getSalt());
|
144 | 136 | if (!entity.getPassword().equals(password)) {
|
145 |
| - listenerAdapter.onAuthorizeFail(username); |
| 137 | + reason = AuthorizationFailedEvent.Reason.PASSWORD_ERROR; |
146 | 138 | throw new BusinessException("{password_error}", 400);
|
147 | 139 | }
|
148 | 140 | // TODO: 17-1-13 获取IP
|
149 | 141 | userService.updateLoginInfo(entity.getId(), "", System.currentTimeMillis());
|
150 | 142 | // 验证通过
|
151 | 143 | Authorization authorization = userService.initUserAuthorization(entity.getId());
|
152 |
| - listenerAdapter.onAuthorizeSuccess(remember, authorization); |
153 |
| - return ok(authorization.getPermissions()); |
| 144 | + AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(authorization, parameterGetter); |
| 145 | + authorizationListenerDispatcher.doEvent(event); |
| 146 | + return ok(entity.getId()); |
| 147 | + } catch (Exception e) { |
| 148 | + AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username, password, parameterGetter, reason); |
| 149 | + failedEvent.setException(e); |
| 150 | + authorizationListenerDispatcher.doEvent(failedEvent); |
| 151 | + throw e; |
154 | 152 | } finally {
|
155 | 153 | //无论如何都清空验证码和私钥
|
156 |
| - session.removeAttribute(VERIFY_CODE_NAME); |
157 |
| - session.removeAttribute(RSA_PRIVATE_KEY_NAME); |
158 |
| - } |
159 |
| - } |
160 |
| - |
161 |
| - class UserAuthorizationListenerAdapter implements UserAuthorizationListener { |
162 |
| - @Override |
163 |
| - public void onConfig(String username, UserAuthorizationConfigRegister configHolder) { |
164 |
| - if (userAuthorizationListeners != null) |
165 |
| - userAuthorizationListeners.forEach(listener -> listener.onConfig(username, configHolder)); |
166 |
| - } |
167 |
| - |
168 |
| - @Override |
169 |
| - public void onAuthorizeBefore(String username) { |
170 |
| - if (userAuthorizationListeners != null) |
171 |
| - userAuthorizationListeners.forEach(listener -> listener.onAuthorizeBefore(username)); |
172 |
| - } |
173 |
| - |
174 |
| - @Override |
175 |
| - public void onAuthorizeFail(String username) { |
176 |
| - if (userAuthorizationListeners != null) |
177 |
| - userAuthorizationListeners.forEach(listener -> listener.onAuthorizeFail(username)); |
178 |
| - } |
179 |
| - |
180 |
| - @Override |
181 |
| - public void onLoginOut(Authorization authorization) { |
182 |
| - if (userAuthorizationListeners != null) |
183 |
| - userAuthorizationListeners.forEach(listener -> listener.onLoginOut(authorization)); |
184 |
| - } |
185 |
| - |
186 |
| - @Override |
187 |
| - public void onAuthorizeSuccess(boolean isRemembered, Authorization authorization) { |
188 |
| - if (userAuthorizationListeners != null) |
189 |
| - userAuthorizationListeners.forEach(listener -> listener.onAuthorizeSuccess(isRemembered, authorization)); |
| 154 | +// session.removeAttribute(VERIFY_CODE_NAME); |
| 155 | +// session.removeAttribute(RSA_PRIVATE_KEY_NAME); |
190 | 156 | }
|
191 | 157 | }
|
192 | 158 |
|
|
0 commit comments