JWTAuthenticationFilter.java中的successAuthentication函数提供了nullpointerexception。您知道为什么这会成为问题吗?使用相同的bean自动装配是否有问题?
这是我当前的项目结构:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Title asdf asdf asdg asgasdg asdfg"
android:textAppearance="?android:textAppearanceLarge"
app:layout_constraintEnd_toStartOf="@+id/text"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteY="66dp" />
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="2015"
android:textAppearance="?android:textAppearanceLarge"
app:layout_constraintBottom_toBottomOf="@+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView3"
app:layout_constraintTop_toTopOf="@+id/textView3" />
</android.support.constraint.ConstraintLayout>
Application.java
-com
-register
-RegisterController.java
-security
-JWTAuthenticationFilter.java
-JWTAuthorizationFilter.java
-SecurityConstants.java
-WebSecurity.java
-user
-User.java
-UserRepository.java
-UserService.java
-Application.java
UserRepository.java
@Configuration
@SpringBootApplication
public class Application {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
UserService.java
@Repository
public interface UserRepository extends MongoRepository<User, String> {
User findByUsername(String name);
User findByEmail(String Email);
User findBy_id(ObjectId id);
}
User.java
@Service
public class UserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = this.userRepository.findByUsername(username);
if(user == null)
return null;
List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("user"));
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
}
public User getUserByUsername(String username) {
return this.userRepository.findByUsername(username);
}
public User getUserBy_id(ObjectId _id) {
return userRepository.findBy_id(_id);
}
public void saveUser(User newUser){
userRepository.save(newUser);
}
}
JWTAuthenticationFilter.java
@Document
public final class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private ObjectId _id;
private String email;
private String username;
private String password;
private AccountProperties accountProperties;
private Address address;
private List<Pet> pets = new ArrayList<>();
private String phoneNumber;
public User() {}
public User(@JsonProperty("email") String email, @JsonProperty("username") String username,
@JsonProperty("password") String password) {
this.email = email;
this.username = username;
this.password = password;
}
public String get_id() { return _id.toHexString();}
getters and setters() ...
}
JWTAuthorizationFilter.java
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Autowired
private UserRepository userRepo;
private AuthenticationManager authenticationManager;
JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
User creds = new ObjectMapper()
.readValue(req.getInputStream(), User.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList<>())
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
String username = ((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername();
String token = JWT.create()
.withSubject(username)
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(HMAC512(SECRET.getBytes()));
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
User u = uRepo.findByUsername("admin");
res.getWriter().write(
"{\"" + SecurityConstants.HEADER_STRING + "\":\"" + SecurityConstants.TOKEN_PREFIX+token + "\"," +
"\"" + "ObjectID" + "\":\"" + u.get_id() + "\"}"
);
}
}
WebSecurity.java
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes()))
.build()
.verify(token.replace(TOKEN_PREFIX, ""))
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
SecurityConstants.java
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userDetailsService;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS );
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(this.userDetailsService).passwordEncoder(this.bCryptPasswordEncoder);}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
RegisterController.java
public class SecurityConstants {
public static final String SECRET = "SecretKeyToGenJWTs";
public static final long EXPIRATION_TIME = 864_000_000; // 10 days
public static final String TOKEN_PREFIX = "Bearer ";
public static final String HEADER_STRING = "Authorization";
public static final String SIGN_UP_URL = "/users/sign-up";
}
答案 0 :(得分:0)
不确定这是否是您问题的根本原因,但是我从未在主应用程序中看到@Configuration
。我会尝试将其移至单独的配置类,看看是否有帮助
答案 1 :(得分:0)
问题在于您没有将JWTAuthenticationFilter定义为Bean
,因此spring不会在其中注入依赖项。
您可以手动将豆放入过滤器中。来自GenericFilterBean javadoc:
此通用过滤器基类与Spring org.springframework.context.ApplicationContext概念无关。过滤器通常不加载自己的上下文,而是从Spring根应用程序上下文访问服务Bean,可通过过滤器的ServletContext访问它(请参阅org.springframework.web.context.support.WebApplicationContextUtils)。
或者您可以将其制成bean。但是,如果您使用的是Spring Boot,请考虑:
容器不了解Spring Security内部的所有过滤器这一事实很重要,尤其是在Spring Boot应用程序中,默认情况下,所有Filter类型的@Beans都会自动向容器注册。因此,如果要向安全链中添加自定义过滤器,则无需使其成为@Bean或将其包装在明确禁用容器注册的FilterRegistrationBean中。
答案 2 :(得分:0)
用@Component注释JWTAuthenticationFilter或在配置文件中添加@Bean。好像没有创建对象