import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.demo.SecurityConfiguration.JwtAuthenticationFilter;
@Configuration
public class SecurityConfiguration {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/login", "/api/signup").permitAll()
)
.addFilterBefore(jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}```
#My Security Configuration blocks all /GET requests to any page. Any idea why?
1 messages · Page 1 of 1 (latest)
Detected code, here are some useful tools:
<@&1004656351647117403> please have a look, thanks.
AFAIK, by default spring security will treat all endpoint accesses as .authenticated(), which in your case would mean that all paths aside from /api/login and /api/signup would at least require some kind auth (in your case user/password).
To allow access for all GET requests WITHOUT auth, you may want to add .requestMatchers(HttpMethod.GET).permitAll() as well
(Please someone CMIIW)
also, it's better to also explicitly specify at least .anyRequest().authenticated() or .anyRequest().permitAll() as you see fit to avoid confusions.
please also note that the rule ordering MATTERS. whichever rules came first would be prioritized over the next.
which means if for example you put .anyRequest().authenticated() as a first rule, it wouldn't matter whatever rules you provide next, they'd all be swallowed by the first rule
My goal is to make only LOGIN AND SIGNUP accessible without any auth, all other endpoints should be protected
But still, the problem is, it still says that access is denied when i go to/login or /signup
are you sure you're accessing /api/login and not /login?
because the endpoint u set in the config is for specifically /api/login
also, I'm not sure what ur trying to achieve by adding both jwt auth and username/password together in addFilterBefore.
do you want the users to be able to login with either token or basic (user/pass) or what?
With jwttoken only
I am practicing jwt
Actually it is my first time implementing login/signup on my own
My idea is:
Through jwttoken extract username then through username extract password from db via my own custom module
I had this same problem too. To my knowledge (CMIIW), the filter you added with addFilterBefore will still nbe run even if you use permitAll(). How I solved it (which may not be optimal, but worked for me so far) was to add an if statement in my filter that would automatically return a successful login if the path matched. ie (in your filter):
if ((request.getRequestURI().startsWith("/api/") {
filterChain.doFilter(request, response);
return;
}
Something like this should work
Detected code, here are some useful tools:
Formatted code
if ((request.getRequestURI().startsWith("/api/") {
filterChain.doFilter(request, response);
return ;
}
I added this to my filter, however, issue is still there
could you send your filter?
Okay, tomorrow.
I have also problem with the Lambock
Apparently java does not see the getters, setters or lambock as a whole since i get "unknown method" when i invoke getUsername()
Dependency is there
Idk what is wrong
@true otter here ```
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtService;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
String path = request.getRequestURI();
if (path.equals("/api/login") || path.equals("/api/signup")) {
filterChain.doFilter(request, response);
return;
}
String authHeader = request.getHeader("Authorization");
String jwt;
String username;
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
jwt = authHeader.substring(7);
try {
username = jwtService.extractUsername(jwt);
} catch (Exception e) {
filterChain.doFilter(request, response);
return;
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtService.isTokenValid(jwt, userDetails.getUsername())) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request)
);
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
} ```
Detected code, here are some useful tools:
Anyone can help pls?
I don't have specific knowledge on the specific Spring Security issue, but for JWTs you usually assume the user is authenticated as JWTs are signed and you know the server emitted it.
I guess it would make more sense that you issue the JWT after the login and not performing the login from a username in a JWT + password in body request
Ok, in the last snippet is seems to make more sense, i was talking about this https://discordapp.com/channels/272761734820003841/1485685037897617419/1485708966930415716
Would it be made this way?
Pull username/password from db -> generate token for the user -> redirect to the other page?
How would the jwt keep information related to the user?
u need to add it in the build section aswell in ur pom.xml
Usually JWTs just carry out information about the user, such as permissions and whatnot, it could simply have its username and that would be enough as you can just pull everything else out of the DB
Did already, still nothing
JWTs are often used to avoid having to keep sessions on the backend, as you issue a token and don't have to worry about when the session expires because the token will have that information
Although keep in mind, you don't need JWTs to have what I described earlier
People misuse JWTs a lot
How do you suggest to implement sign up and login?
Is this just one service?
Why not a simple cookie session?
Users enters password and username on a form, POST, on the backend you validate username and password, if it's correct you start a session (you will need some backend place to keep these) and you send a cookie to the user that identifies the session
Another even more basic authentication method is to require the Authentication header with Basic username:password on every request
I plan to do multiple service
Login/signup is one separate service
Services*
Then JWTs is actually appropriate
I still don't know why it says access denied to "/login" and signup even though i wrote an exception for those two in my filter?
in your allowed endpoints doesnt exist for /login but /api/login
could you add "/login" with in your requestMatchers ? like .requestMatchers("/api/login","/login", "/api/signup").permitAll()
also suggest you to check if your system works before enabling spring security , ( i mean maybe there is another problem on your get/post request controllers but you missed them ) so first just disable springsecurity and check if everthing working or not then enable it
this is my controller ```import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.stereotype.Controller;
@Controller
public class SecurityControllers {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/signup")
public String signup() {
return "signup";
}
}```
Detected code, here are some useful tools:
it works with the "/**" as a path though