Spring security cannot access userService while login NullPointerException - spring-boot

When making post request to login this error shows up telling me that userService is null.
When I create an object of UserService instead of autowiring it it passes it but tell me that the repository called in userService is null. The repository is autowired and i cannot instanciate it because its an interface.
Here is the service class:
#Service
public class MyUserDetailsService implements UserDetailsService {
#Autowired
UserService userService;
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new MyUserDetails(userService.getByUsernameOrEmail(s));
}
}
And this is the security configuration class:
Also I am creating an object of MyUserService because spring cannot autowire it telling me that no bean have such name.
#Configuration
#EnableWebSecurity
public class UserSercurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new MyUserDetailsService());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.anyRequest().hasRole(UserType.ADMIN.toString())
.and().formLogin();
}
#Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}

You cannot instantiate method or variables in your repository as it is an interface but you can autowire your repository class to use your method declared in userRepository interface, you have to autowire your repository class.You can do it this way as I have done in the below code.
Your service class should be like this:
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Users user = userRepository.getUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("Could not find user");
}
return new MyUserDetails(user);
}
And your repository should be like this:
#Repository
public interface UserRepository extends JpaRepository<Users, Long> {
#Query("SELECT u FROM Users u WHERE u.name = ?1")
public Users getUserByUsername(String username);
}
And also autowire UserDetailsService in your configuration class and pass the instance userDetailsService in your configure(AuthenticationManagerBuilder auth) method, UserDetailsService provides you instance of your MyUserDetailService class.
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Bean
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.and()
.formLogin().permitAll()
.defaultSuccessUrl("/", true)
.and()
.logout().permitAll()
.logoutSuccessUrl("/");
}
Try to implement in this way, If this is solution of your question please let me know and if you still have doubt feel free to ask.

Related

Can't inject dependencies in Spring Security configuration

I have a spring project using Spring Security. I want to inject dependencies into my WebSecurityConfigurerAdapter extending class but the dependencies do not seem to be getting injected. My controllers also use dependency injection and it does work there.
My SecSecurity class:
#Configuration
#Component
#EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserPrincipalDetailsService userPrincipalDetailsService;
LogoutSuccessHandler handler = new LogoutSuccess();
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
http. logout().and().
httpBasic()
.and()
.authorizeRequests()
.antMatchers( "/", "/home", "/user", "/vestigingen", "/available", "/logout").permitAll()
.anyRequest().authenticated()
.and().logout().logoutSuccessHandler(handler).deleteCookies("JSESSIONID").invalidateHttpSession(false).permitAll()
.and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
#Bean
public UserDetailsService userDetailsService() {
return new UserPrincipalDetailsService();
}
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);
return daoAuthenticationProvider;
}
}
It cannot find beans for the userPrincipalDetailsService class.
UserPrincipalDetailService class:
#Component
public class UserPrincipalDetailsService implements UserDetailsService {
private UserRepositorySQL userRepository = new UserRepositorySQL();
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
UserEntity user = userRepository.findUserByUsername(s);
UserPrincipal userPrincipal = new UserPrincipal(user);
return userPrincipal;
}
}
to clarify: I can't inject any dependencies within my SecSecurityConfig class eventhough i have tried annotating it in many different ways.
Define the bean name #Component("userPrincipalDetailsService") in the UserPrincipalDetailsService class.
#Component("userPrincipalDetailsService")
public class UserPrincipalDetailsService implements UserDetailsService {
private UserRepositorySQL userRepository = new UserRepositorySQL();
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
UserEntity user = userRepository.findUserByUsername(s);
UserPrincipal userPrincipal = new UserPrincipal(user);
return userPrincipal;
}
}

Spring boot and jwt Encoded password does not look like BCrypt

I know there are several questions about this, but none of them helped, everything seemed ok to me... I hope I'm wrong about this.
I've followed this tutorial to create authentication with JWT for my Spring Boot application, but I'm stuck with this warning
o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
This is the class that extends WebSecurityConfigurerAdapter:
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()));
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
}
And this is the class that implements UserDetailsService:
public class UserDetailsServiceImpl implements UserDetailsService {
private ApplicationUserRepository applicationUserRepository;
public UserDetailsServiceImpl(ApplicationUserRepository applicationUserRepository) {
this.applicationUserRepository = applicationUserRepository;
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("loadUserByUsername");
ApplicationUser applicationUser = applicationUserRepository.findByUsername(username);
if (applicationUser == null) {
System.out.println("User non trovato");
throw new UsernameNotFoundException(username);
}
System.out.println("Username: " + applicationUser.getUsername());
return new User(applicationUser.getUsername(), applicationUser.getPassword(), emptyList());
}
}
Also, I'm wondering where the class WebSecurity is istantiated with the correct parameters passed. Is this managed automatically by Spring?
Found the problem, it was that my class UserDetailsServiceImpl did not have the "#Service" annotation. Now it's working fine.

How to renew access token with the refresh token in oauth2 in spring?

I am very new to spring and it is my first attempt at spring security with oauth2. I have implemented OAuth2 with spring security and I do get the access token and the refresh token. However, while sending the refresh token to get the new access token I got "o.s.s.o.provider.endpoint.TokenEndpoint - IllegalStateException, UserDetailsService is required."
The solution to similar problem by other users appeared to be attaching UserDetailsService with the endpoint.
So I did the same and now when I try to send the request to with grant_type: refresh_token and refresh_token: THE TOKEN along with the client id and secret, I get an error that the user was not found.
Please refer the WebSecurityConfiguration class below:
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private UserDetailsService customUserDetailsService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean ();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService)
.passwordEncoder(encoder());
}
#Override
protected void configure (HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/login**")
.permitAll()
.anyRequest()
.authenticated();
}
public PasswordEncoder encoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Please refer the AuthorizationServerConfiguration class below:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private DataSource dataSource;
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
.userDetailsService(userDetailsService);
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
}
Please refer the ResourceServerConfiguration class below:
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
#Autowired
DataSource dataSource;
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("scout").tokenStore(tokenStore());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests (). antMatchers ("/oauth/token", "/oauth/authorize **").permitAll();
// .anyRequest (). authenticated ();
http.requestMatchers (). antMatchers ("/api/patients/**") // Deny access to "/ private"
.and (). authorizeRequests ()
.antMatchers ("/api/patients/**"). access ("hasRole ('PATIENT')")
.and (). requestMatchers (). antMatchers ("/api/doctors/**") // Deny access to "/ admin"
.and (). authorizeRequests ()
.antMatchers ("/api/doctors/**"). access ("hasRole ('DOCTOR')");
}
}
The CustomUserDetailsService class for reference if required:
#Service
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UsersRepository userRepository;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Optional<Users> usersOptional = userRepository.findByEmail(email);
Users user = null;
if(usersOptional.isPresent()) {
System.out.println(usersOptional.isPresent());
user = usersOptional.get();
}else {
throw new RuntimeException("Email is not registered!");
}
return new CustomUserDetails(user);
}
}
As I think, the server should only check for the validity of the refresh token as we don't pass the user details with refresh token. So I don't know why it requires the userDetails in the first place.
Please help and guide if I am missing something!
Thanks in advance.
I don't sure. But as I see your code in WebSecurityConfiguration could wired default InMemoryUserDetailsManager UserDetailsService .That could be reason why you have 2 different provider. In one you write, from the other you read users. Please try change your code as I show below and let me know if it help:
Was:
#Autowired
private UserDetailsService customUserDetailsService;
My vision how should be:
#Autowired
private CustomUserDetailsService customUserDetailsService;

How to Control Sequence of Bean Creating and Component Scanning In Spring Boot

Updated
I am Beginner to Spring and I tried to implement spring security application using Java Based Configuration. But now I have to Control sequence of bean creating and component scanning of application.
This is my configuration class
#EnableWebSecurity
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public Md5PasswordEncoder passwordEncoder() {
return new Md5PasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().cacheControl();
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authProxy").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JWTLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
and here is the JWTLoginFilter
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher("/login"));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
#Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(httpServletRequest.getInputStream(), AccountCredentials.class);
final Authentication authentication = getAuthenticationManager()
.authenticate(new UsernamePasswordAuthenticationToken(credentials.getUsername(),
credentials.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
String name = authentication.getName();
tokenAuthenticationService.addAuthentication(response, name);
}
}
This is working fine.
But all thing going wrong When I try to declare JWTLoginFilter as service with #Service annotation and while I am trying to Autowire that.
The Changes that I did as Follows.
this is configuration class.
#EnableWebSecurity
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public Md5PasswordEncoder passwordEncoder() {
return new Md5PasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
JWTLoginFilter jwtLoginFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().cacheControl();
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authProxy").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtLoginFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
And this is my new JWTLoginFilter
#Service
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
#Autowired
AuthenticationManager authenticationManager;
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter() {
super(new AntPathRequestMatcher("/login"));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
#Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(httpServletRequest.getInputStream(), AccountCredentials.class);
final Authentication authentication = getAuthenticationManager()
.authenticate(new UsernamePasswordAuthenticationToken(credentials.getUsername(),
credentials.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
String name = authentication.getName();
tokenAuthenticationService.addAuthentication(response, name);
}
}
This Code gives runtime error called
Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'JWTLoginFilter' defined in file [/media/dilanka/Stuff/CODEBASE/Inspection-Application/Inspection-AuthProxy/target/classes/com/shipxpress/inspection/security/jwt/JWTLoginFilter.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: authenticationManager must be specified
The error is as my thought at the beginning, ComponentScan Scanning and initiating JWTLoginFilter. But at that time AuthenticationManager bean has not created. So It is not auto wiring.
So I have to create AuthenticationManager bean before scanning JWTLoginFilter, But It is not possible because it has to create in class that extended by WebSecurityConfigurerAdapter and spring allows one WebSecurityConfigurerAdapter extended class. So I can't initiate it in another class.
Also
#Override
protected void configure(HttpSecurity http) throws Exception {}
has to declare in WebSecurityConfigurerAdapter extended class and this method use jwtLoginFilter. So all
#Autowired
JWTLoginFilter jwtLoginFilter;
and
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
and
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().cacheControl();
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authProxy").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtLoginFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
has to define it in WebSecurityConfig extends WebSecurityConfigurerAdapter class and has to Control sequence of bean creating and component scanning of the application. Does anyone have an idea? please help me.
updated-->
I Tried to implement JWTLoginFilter as follows,
#Service
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
private TokenAuthenticationService tokenAuthenticationService;
#Autowired
public JWTLoginFilter(AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher("/login"));
}
...
}
But it gives the following error
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| JWTLoginFilter defined in file [/media/dilanka/Stuff/CODEBASE/Inspection-Application/DR-136812421-dbchangesSendAsMail/Inspection-Application/Inspection-AuthProxy/target/classes/com/shipxpress/inspection/security/jwt/JWTLoginFilter.class]
↑ ↓
| webSecurityConfig (field com.shipxpress.inspection.security.jwt.JWTLoginFilter com.shipxpress.inspection.config.WebSecurityConfig.jwtLoginFilter)
└─────┘
I think the problem is, If we auto wire Constructor as above, Then JWTLoginFilter can't create without creating Configuration beans creating. But Configuration beans needs JWTLoginFilter bean. So it can't create without JWTLoginFilter bean.
Thanks.
#Autowired annotation will be processed after constructor of bean has been called. So your exception does not depend on the sequence of bean creating. If you need to invoke setAuthenticationManager from constructor you can apply #Autowired to the constructor:
#Service
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
AuthenticationManager authenticationManager;
private TokenAuthenticationService tokenAuthenticationService;
#Autowired
public JWTLoginFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager; //if you will need this instance in future
super(new AntPathRequestMatcher("/login"));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
...
}
Then appropriate bean will be passed to the constructor automatically.
Another solution is to make all initialization in the #PostConstruct method. This method will be called just after #Autowired annotation has been processed:
#Service
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
#Autowired
AuthenticationManager authenticationManager;
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(){
super(new AntPathRequestMatcher("/login"));
}
#PostConstruct
public void postConstruct() {
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
...
}
Spring Boot has multiple conditional annotations to use like #ConditionalOnBean to control the sequencing of bean creation
Look into package org.springframework.boot.autoconfigure.condition for all the conditionals available
For the your example, best way is to have constructor injection of AuthenticationManager in JWTLoginFilter

Autowired CrudRepository into UserDetailsService is always null

I'm newbie in Spring-World, I have a Spring Boot application with Spring Security and JPA. Also have CrudRepository and UserDetailsService, see below
Application class
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
UserDao
#Repository
public interface UserDao extends CrudRepository<User, Long> {
public Collection<User> findByName(String name);
}
ApiUserDetailsService
#Component
public class ApiUserDetailsService implements UserDetailsService {
#Autowired
private UserDao dao;
#Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
assert dao != null;
...
}
}
Security Config
#Configuration
#EnableWebSecurity
public class HttpBasicAuthConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestCache().requestCache(new NullRequestCache());
http.httpBasic();
http.authorizeRequests().anyRequest().authenticated();
}
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new ApiUserDetailsService());
}
}
Why Autowired dao is always null? What I do wrong?
You are creating the ApiUserDetailsService manually, in the the method:
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new ApiUserDetailsService());
}
What you want is:
#Configuration
#EnableWebSecurity
#EnableJpaRepositories(basePackages = {"your.package.dao"})
public class HttpBasicAuthConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestCache().requestCache(new NullRequestCache());
http.httpBasic();
http.authorizeRequests().anyRequest().authenticated();
}
// register ApiUserDetailsService as a bean
#Bean
public UserDetailsService apiUserDetailsService() {
return new ApiUserDetailsService();
}
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
// get the autowired bean from Spring
auth.userDetailsService(apiUserDetailsService());
}
}

Resources