mirror of https://github.com/halo-dev/halo
Complete admin login api
parent
42032e3b78
commit
dd2caca58d
|
@ -81,7 +81,7 @@ public class HaloConfiguration {
|
|||
public FilterRegistrationBean<AdminAuthenticationFilter> adminAuthenticationFilter(HaloProperties haloProperties,
|
||||
ObjectMapper objectMapper,
|
||||
StringCacheStore cacheStore) {
|
||||
AdminAuthenticationFilter adminFilter = new AdminAuthenticationFilter(cacheStore);
|
||||
AdminAuthenticationFilter adminFilter = new AdminAuthenticationFilter(cacheStore, "/admin/api/login");
|
||||
// Set failure handler
|
||||
adminFilter.setFailureHandler(new AdminAuthenticationFailureHandler(haloProperties.getProductionEnv(), objectMapper));
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@ public class UserOutputDTO implements OutputConverter<UserOutputDTO, User> {
|
|||
|
||||
private String description;
|
||||
|
||||
private Date expireTime;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private Date updateTime;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cc.ryanc.halo.model.params;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* Login param.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/28/19
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
public class LoginParam {
|
||||
|
||||
@NotBlank(message = "Username or email must not be blank")
|
||||
@Size(max = 255, message = "Length of username or email must not be more than {max}")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "Password must not be blank")
|
||||
@Size(max = 100, message = "Length of password must not be more than {max}")
|
||||
private String password;
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
|
@ -20,6 +21,9 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
|
@ -48,8 +52,14 @@ public class AdminAuthenticationFilter extends OncePerRequestFilter {
|
|||
|
||||
private final StringCacheStore cacheStore;
|
||||
|
||||
public AdminAuthenticationFilter(StringCacheStore cacheStore) {
|
||||
private final Collection<String> excludeUrlPatterns;
|
||||
|
||||
private final AntPathMatcher antPathMatcher;
|
||||
|
||||
public AdminAuthenticationFilter(StringCacheStore cacheStore, String... excludeUrls) {
|
||||
this.cacheStore = cacheStore;
|
||||
this.excludeUrlPatterns = excludeUrls == null ? Collections.emptyList() : Collections.unmodifiableCollection(Arrays.asList(excludeUrls));
|
||||
antPathMatcher = new AntPathMatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,6 +103,11 @@ public class AdminAuthenticationFilter extends OncePerRequestFilter {
|
|||
failureHandler.onFailure(request, response, new AuthenticationException("You have to login before accessing admin api"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||
return excludeUrlPatterns.stream().anyMatch(p -> antPathMatcher.match(p, request.getServletPath()));
|
||||
}
|
||||
|
||||
public void setFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
this.failureHandler = failureHandler;
|
||||
}
|
||||
|
@ -117,4 +132,5 @@ public class AdminAuthenticationFilter extends OncePerRequestFilter {
|
|||
|
||||
return token;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package cc.ryanc.halo.security.support;
|
|||
|
||||
import cc.ryanc.halo.exception.AuthenticationException;
|
||||
import cc.ryanc.halo.model.entity.User;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
|
@ -13,6 +15,8 @@ import org.springframework.lang.NonNull;
|
|||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserDetail {
|
||||
|
||||
private User user;
|
||||
|
|
|
@ -6,6 +6,7 @@ import cc.ryanc.halo.model.params.UserParam;
|
|||
import cc.ryanc.halo.service.base.CrudService;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
|
@ -70,10 +71,11 @@ public interface UserService extends CrudService<User, Integer> {
|
|||
*
|
||||
* @param key username or email must not be blank
|
||||
* @param password password must not be blank
|
||||
* @param httpSession http session must not be null
|
||||
* @return user info
|
||||
*/
|
||||
@NonNull
|
||||
User login(@NonNull String key, @NonNull String password);
|
||||
User login(@NonNull String key, @NonNull String password, @NonNull HttpSession httpSession);
|
||||
|
||||
/**
|
||||
* Updates user password.
|
||||
|
|
|
@ -6,6 +6,8 @@ import cc.ryanc.halo.exception.NotFoundException;
|
|||
import cc.ryanc.halo.model.entity.User;
|
||||
import cc.ryanc.halo.model.params.UserParam;
|
||||
import cc.ryanc.halo.repository.UserRepository;
|
||||
import cc.ryanc.halo.security.filter.AdminAuthenticationFilter;
|
||||
import cc.ryanc.halo.security.support.UserDetail;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.service.base.AbstractCrudService;
|
||||
import cc.ryanc.halo.utils.DateUtils;
|
||||
|
@ -15,6 +17,7 @@ import org.springframework.lang.NonNull;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -72,9 +75,10 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public User login(String key, String password) {
|
||||
public User login(String key, String password, HttpSession httpSession) {
|
||||
Assert.hasText(key, "Username or email must not be blank");
|
||||
Assert.hasText(password, "Password must not be blank");
|
||||
Assert.notNull(httpSession, "Http session must not be null");
|
||||
|
||||
// Ger user by username
|
||||
User user = Validator.isEmail(key) ? getByEmailOfNonNull(key) : getByUsernameOfNonNull(key);
|
||||
|
@ -105,7 +109,8 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
throw new BadRequestException("账号或者密码错误,您还有" + (MAX_LOGIN_TRY - loginFailureCount) + "次机会");
|
||||
}
|
||||
|
||||
// TODO Set session or cache token
|
||||
// Set session
|
||||
httpSession.setAttribute(AdminAuthenticationFilter.ADMIN_SESSION_KEY, new UserDetail(user));
|
||||
|
||||
return user;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package cc.ryanc.halo.web.controller.admin.api;
|
||||
|
||||
import cc.ryanc.halo.model.dto.CountOutputDTO;
|
||||
import cc.ryanc.halo.model.dto.UserOutputDTO;
|
||||
import cc.ryanc.halo.model.enums.BlogProperties;
|
||||
import cc.ryanc.halo.model.enums.PostStatus;
|
||||
import cc.ryanc.halo.model.enums.PostType;
|
||||
import cc.ryanc.halo.service.AttachmentService;
|
||||
import cc.ryanc.halo.service.CommentService;
|
||||
import cc.ryanc.halo.service.OptionService;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.model.params.LoginParam;
|
||||
import cc.ryanc.halo.service.*;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* Admin controller.
|
||||
|
@ -31,11 +31,18 @@ public class AdminController {
|
|||
|
||||
private final OptionService optionService;
|
||||
|
||||
public AdminController(PostService postService, AttachmentService attachmentService, CommentService commentService, OptionService optionService) {
|
||||
private final UserService userService;
|
||||
|
||||
public AdminController(PostService postService,
|
||||
AttachmentService attachmentService,
|
||||
CommentService commentService,
|
||||
OptionService optionService,
|
||||
UserService userService) {
|
||||
this.postService = postService;
|
||||
this.attachmentService = attachmentService;
|
||||
this.commentService = commentService;
|
||||
this.optionService = optionService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping("counts")
|
||||
|
@ -48,4 +55,10 @@ public class AdminController {
|
|||
countOutputDTO.setEstablishDays(Long.valueOf(optionService.getByProperty(BlogProperties.WIDGET_DAYCOUNT).orElse("0")));
|
||||
return countOutputDTO;
|
||||
}
|
||||
|
||||
@PostMapping("login")
|
||||
@ApiOperation("Logins with session")
|
||||
public UserOutputDTO login(@Valid @RequestBody LoginParam loginParam, HttpServletRequest request) {
|
||||
return new UserOutputDTO().convertFrom(userService.login(loginParam.getUsername(), loginParam.getPassword(), request.getSession()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package cc.ryanc.halo.utils;
|
||||
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* BCrypt test.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/28/19
|
||||
*/
|
||||
public class BcryptTest {
|
||||
|
||||
@Test
|
||||
public void cryptTest() {
|
||||
String cryptPassword = BCrypt.hashpw("opentest", BCrypt.gensalt());
|
||||
System.out.println("Crypt password: " + cryptPassword);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue