Cảm ơn. Tôi đã tạo một lớp lọc tùy chỉnh để xác thực người dùng dựa trên ba tham số - tên người dùng, mật khẩu và id tài khoản. Tôi autowired nó như là một bean trong lớp SecurityConfig:
@Bean
public AccountCredentialsAuthenticationFilter accountCredentialsAuthenticationFilter()
throws Exception {
AccountCredentialsAuthenticationFilter accountCredentialsAuthenticationFilter = new AccountCredentialsAuthenticationFilter();
accountCredentialsAuthenticationFilter
.setAuthenticationManager(authenticationManagerBean());
return accountCredentialsAuthenticationFilter;
}
Vì vậy, thay vì chỉ các thông tin username và mật khẩu truyền thống, tôi đã có thể thực hiện xác thực sử dụng ba lĩnh vực (username, mật khẩu và tài khoản id) bằng cách gọi thích hợp phương pháp dịch vụ cần thiết để thẩm định và cơ quan chức năng thiết lập cho người dùng đăng nhập:
public class AccountCredentialsAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Autowired
private UserService userService;
@Qualifier("authenticationManager")
protected AuthenticationManager authenticationManager;
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
String account = request.getParameter("account");
final String userName = request.getParameter("userName");
final String password = request.getParameter("password");
boolean isFound = userService.checkLogin(userName, password, account);
if (isFound == true) {
boolean selectedAccount = false;
UserDetails userDetails = userService.loadUserByUsername(userName);
User user = (User) userDetails;
Set<Account> accounts = user.getAccounts();
String acctSelect = null;
// user has multiple accounts
for (Account acct : accounts) {
acctSelect = acct.getAccountId().toString();
if (acctSelect.equals(account)) {
// confirm which account user has logged in with
selectedAccount = true;
account = acctSelect;
request.getSession().setAttribute("account", account);
break;
}
}
if (selectedAccount) {
Set<? extends GrantedAuthority> authorities = (HashSet<? extends GrantedAuthority>) userDetails
.getAuthorities();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userName, password,
authorities);
token.setDetails(new WebAuthenticationDetails(request));
super.setDetails(request, token);
Authentication auth = this.getAuthenticationManager().authenticate(token);
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(auth);
// Create a new session and add the security context.
HttpSession session = request.getSession(true);
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
return auth;
} else {
SecurityContextHolder.getContext().setAuthentication(null);
request.getSession().setAttribute("SPRING_SECURITY_CONTEXT", null);
throw new UsernameNotFoundException("Please input correct credentials");
}
} else {
SecurityContextHolder.getContext().setAuthentication(null);
request.getSession().setAttribute("SPRING_SECURITY_CONTEXT", null);
throw new UsernameNotFoundException("Please input correct credentials");
}
}
tôi overrode phương pháp của lớp UsernamePasswordAuthenticationFilter để chuyển hướng thích hợp sau khi xác thực & ủy quyền sau:
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, "/home");
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, "/login?error=true");
}
Tôi cũng sửa đổi phương pháp cấu hình trong lớp SecurityConfig để thực hiện các bộ lọc tùy chỉnh:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(accountCredentialsAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()....rest of the code....}
Đối với chứng thực tùy chỉnh trong Xuân An, phương pháp
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){---- call service methods here ----}
trong lớp bộ lọc này (AccountCredentialsAuthenticationFilter) làm cho phương thức sau trong lớp điều khiển dự phòng:
@RequestMapping(value = { "/login" }, method = RequestMethod.POST)
public String loginPage(@Valid @ModelAttribute("user") User user, BindingResult result, ModelMap model, HttpServletRequest request){---- call ervice methods here ----}
theo câu trả lời tôi sẽ thêm một bộ lọc và lưu trữ dữ liệu bổ sung trong phiên, nhưng làm thế nào tôi sẽ nhận được đối tượng phiên hoặc yêu cầu đối tượng trong lớp UserDetailsService này không được đề cập trong câu trả lời, xin vui lòng giúp tôi – Krushna