我需要獲取當前登錄用戶的用戶物件詳細資訊,以便我可以獲得分配給用戶的客戶,但是當我列印到控制臺時,我一直得到一個空物件。我可以使用為用戶型別生成的令牌成功登錄,但是當 Spring 身份驗證查詢登錄的用戶名時,我一直收到空回應。
控制器
@RestController
public class CustomerController {
@Autowired
CustomerAccountService customerRepo;
@Autowired
UserAccountService userRepo;
@GetMapping(value="marketers/customers")
public List<Customer> getLlistByMarketerName()
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
User loggedInUser = userRepo.findByUserName(authentication.getName());
System.out.println("logged in user:" loggedInUser);
return customerRepo.findByMarketer(loggedInUser);
}
存盤庫
public interface CustomerAccountRepo extends JpaRepository <Customer, Long >
{
@Query("select customer from Customer customer join customer.marketer marketer where marketer = :marketer")
List<Customer> findByMarketer(User marketer);
}
用戶詳細資訊服務
@Service
public class UserAccountService implements UserDetailsService {
@Autowired
private UserAccountRepository userRepository;
private PasswordEncoder bCryptPasswordEncoder;
public UserAccountService (PasswordEncoder bCryptPasswordEncoder) {
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUserName(username);
if(user == null) {
throw new UsernameNotFoundException("User not found");
}
// List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority(user.getUserRole()));
return MyUserDetails.build(user);
}
JWT 請求過濾器
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenUtil jwtTokenUtil;
private final UserAccountService userAccountService;
@Autowired
public JwtRequestFilter( @Lazy final UserAccountService userAccountService) {
this.userAccountService = userAccountService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
if (requestTokenHeader != null) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
System.out.println("JWT Token has expired");
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userAccountService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
String authorities = userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority)
.collect(Collectors.joining());
System.out.println("Authorities granted : " authorities);
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
else {
System.out.println("Not Valid Token");
}
}
chain.doFilter(request, response);
}
用戶物體
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String firstName ;
private String lastName;
@Column(name="user_name", unique=true)
private String userName;
private String password;
private String Gender;
private String phoneNumber;
private String email;
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@ManyToOne(targetEntity = Branch.class,
fetch = FetchType.LAZY )
@JoinColumn(name="branch_id")
private Branch branch;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createdDate;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<UserRole> userRole = new HashSet<>();
@Enumerated(EnumType.STRING)
private UserStatus status;
@JsonBackReference
@OneToMany(mappedBy="marketer",cascade = CascadeType.ALL, targetEntity=Customer.class)
private List <Customer> customer;
這是MyUserDetails 類,提供用戶名和密碼身份驗證詳細資訊
public class MyUserDetails implements UserDetails {
private static final long serialVersionUID = -2456373662763511974L;
private Long id;
private String username;
private String password;
private String email;
private Collection<? extends GrantedAuthority> authorities;
public MyUserDetails() {}
public MyUserDetails(Long id, String username, String email, String password,
Collection<? extends GrantedAuthority> authorities)
{
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static MyUserDetails build(User user) {
List<GrantedAuthority> authorities = user.getUserRole()
.stream().map(role -> new SimpleGrantedAuthority
(role.getName()))
.collect(Collectors.toList());
return new MyUserDetails(user.getId(),
user.getUserName(),
user.getEmail(),
user.getPassword(),
authorities);
}
更新:安全組態檔。這是我在 Java 中的第一個大專案,請原諒我的錯誤
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService myUserDetailsService;
public void addResourceHandlers(ResourceHandlerRegistry registry) {
exposeDirectory("customer-photos", registry);
}
private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) {
Path uploadDir = Paths.get(dirName);
String uploadPath = uploadDir.toFile().getAbsolutePath();
if (dirName.startsWith("../")) dirName = dirName.replace("../", "");
registry.addResourceHandler("/" dirName "/**").addResourceLocations("file:/" uploadPath "/");
}
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(PasswordEncoder passwordEncoder, UserDetailsService userDetailsService) {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/auth/login", "/validate", "/**").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.formLogin().permitAll()
.and()
.sessionManagement()
.maximumSessions(1)
.and()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/auth/login")
.deleteCookies("JSESSIONID");
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
uj5u.com熱心網友回復:
在我看來,您不希望所有端點都不需要身份驗證。為了實作它,您需要/**從permitAll()安全配置中洗掉,如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/auth/login", "/validate").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.formLogin().permitAll()
.and()
.sessionManagement()
.maximumSessions(1)
.and()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/auth/login")
.deleteCookies("JSESSIONID");
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/360457.html
標籤:爪哇 弹簧靴 弹簧 mvc 弹簧安全 弹簧数据-jpa
上一篇:如何在spring框架中使用.properties/.xml/.yml之類的組態檔配置annotaion值?
下一篇:我如何從控制器獲取資料串列
