I'm fairly new to spring security and I'm trying to disable the HTTP 'TRACE' method on my Spring webapp with Embedded Jetty server 7.5, but it doesn't seem to work. I tried a couple of ways based on questions asked on Stackoverflow, but still no luck.
here are my approaches:
Adding a Separate interceptor as suggested here:
My Context.xml looked like:
<interceptors>
<interceptor>
<mapping path="/**"/>
<beans:bean class="com.mypackage.HTTPMethodsInterceptor" />
</interceptor>
<interceptor>.... </interceptor>
</interceptors>
My Interceptor class:
public class HTTPMethodsInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if (!request.getMethod().equalsIgnoreCase("POST")
&& !request.getMethod().equalsIgnoreCase("GET")
&& !request.getMethod().equalsIgnoreCase("PUT")
&& !request.getMethod().equalsIgnoreCase("DELETE")) {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Unauthorized Request");
return false;
} else {
return true;
}
}
}
This doesn't work even on my local. I tried debugging and putting a breakpoint interceptor class, but the breakpoint is not hit anytime.
Please let me know if I am doing something wrong or is there any correct way to implement this?
Thanks!
Related
I am aware that swagger-ui can be fully disabled using #Profile on spring-boot application but I still want certain privileged user to be able to access swagger-ui and not fully disabled.
Is there a way to achieve this.
update:
currently I am using interceptor approach but i don't want this approach.
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if(request.getRequestURI().contains("swagger") &&
!request.isUserInRole("XX_YY_ZZ")) {
response.sendError(403, "You are not authorized to access "); }
return super.preHandle(request, response, handler);
}
Without version you use, or codes, it is difficult to help. But I'll try as best as I can.
When you are using swagger-ui, you have an exposed URL to access your docs (usually, /swagger-ui.html).
You are using spring-boot, and talking about user restriction, so I assume you can use spring-boot-starter-security.
With spring-boot-starter-security, you can configure easily what URL you want to protect (regarding user roles for instance).
Here is a sample configuration that works:
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// the rest of your configuration
http.authorizeRequests().mvcMatchers("/swagger-ui.html").hasRole("DEVELOPER")
}
You can secure swagger URLs just like any URLs you expose with your Controllers.
For more information:
A similar issue:
How to configure Spring Security to allow Swagger URL to be accessed without authentication
Spring security configuration:
https://spring.io/guides/gs/securing-web/
I could help more with:
An extract of your security configuration
The version of Spring-boot you're using
I would suggest adding an interceptor or you can handle it in your exiting interceptor if you have any.
In the spring configuration file:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/swager-url" />
<ref bean="swagerInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<bean id="swagerInterceptor" class="com.security.SwagerInterceptor">
<property name="userService" ref="userService" />
</bean>
The interceptor class can be written similar to this:
public class SwagerInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//Take out user information from the request and validate
}
The last couple of days, I have been struggling with an issue. I've created a rest service hosted by a Grizzly server inside an OSGi container. Everything is working perfectly at this point.
Now, I want to add a header in every response.Not so complex or illogical right? Yet, I can't find a way to do it.
I have tried to:
1) Get the response object inside the rest functions as this question suggests (pretty textbook when you are not under OSGi).
2) Add a handler using the code above (in this case the service method is never called)
server.getServerConfiguration().addHttpHandler(
new HttpHandler() {
#Override
public void service(Request arg0, Response arg1)
throws Exception {
arg1.setHeader("Access-Control-Allow-Origin", "*");
}
});
I am using jersey-server/client/core 1.18.1 and grizzly2-server 1.18.1, hence i prefer a solution that can be applied in this version, but I am willing to update jar versions if it cannot be done in 1.18.x.
You could give a try to Jersey filters.
In a nutshell, you should create class implementing ContainerResponseFilter:
public class MyFilter implements ContainerResponseFilter {
#Override
public void filter(
ContainerRequest request,
ContainerResponse response
) throws IOException {
request.getHttpHeaders().add(<header name>, <header value>);
}
}
Then, you should register this filter in your Jersey server configuration.
Please, note, that this filter would be invoked on every response. To bind it only to specific resources, you could use annotation-binding, that is described here.
All other information you could find here.
I do like to experiment on JBoss from a long time.
Now I am facing some problem during authentication on role management with Resteasy on JBoss7.1.
Let me explain the problem.
Just i started a simple Web Application on Jboss7 with implementation of Resteasy. I am able to login by authenticating the user-role. The Problem comes when i am trying to logout. I found during Login if you do securityContext.getUserPrinicials.getName() , The username is the output as that is authenticated. But there is no session is managed for that user. so what would be the best way to implement the Logout functionality. I am pretty new to Jboss7 and Resteasy both.. Apology if i have said anything wrong..
Thanks In Advance
I am also new to Resteasy .Servlet 3.0 module has something to do this.
I got some idea from here.
As you have not given your sample code i have tested this following code for logout that is working fine..
//import things
#Path("/userrealam")
public class UserService {
#Context HttpServletRequest request;
#Context HttpServletResponse response;
#GET
#Path("logout")
#Produces({MediaType.TEXT_PLAIN})
public void logout() throws JAXBException, IOException {
try {
if (request.getUserPrincipal() != null){
request.logout();
}
}
catch (Exception e) {
}
}
}
I've got spring security successfully evaluating a #PreAuthorize on my controller. If i use "permitAll" then I can view the page, and if I use "isAuthenticated()" then I get an ugly Access is Denied stack trace. If I put the configuration in an intercept-url within the http node in my security context configuration xml file then I am nicely redirected to the login page instead of getting the nasty stack trace right in my page.
Is there a way for me to get the redirection with the annotation mechanism only?
I got this to work. There were a couple of things I had to deal with.
First, my Spring MVC configuration had a SimpleMappingExceptionResolver with a defaultErrorView configured. That was intercepting the Authentication and Authorization errors before they could get to the access-denied-handler that I had configured in the http element in my security configuration. The final code looks something like this.
securitycontext.xml
<global-method-security pre-post-annotations="enabled"/>
<!-- HTTP security configurations -->
<http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<access-denied-handler ref="myAccessDeniedHandler" />
... other configuration here ...
</http>
<!-- handler for authorization failure. Will redirect to the login page. -->
<beans:bean id="myAccessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/index" />
</beans:bean>
note that the loginUrlAuthenticationEntryPoint is actually not a part of the solution, it's the access-denied-handler.
my mvc-config.xml still has the SimpleMappingExceptionResolver, but with no defaultErrorView configured. If I were to continue with this path, I would probably implement my own SimpleMappingExceptionResolver that would let Authentication and Authorization excpetions pass through, OR configure it in the SimpleMappingExceptionResolver instead.
The killer in this deal is that I haven't found a way to configure the requires-channel="https" from the intercept-url through an annotation, so I'll be putting it in the xml configuration file for now anyway.
You can customize your error handling by overriding the security entry point. All exceptions that happen in the filter chain (defined by the mapping you define in the web.xml file) for secure objects get caught and can be handled there. If they are not handled then the ExceptionTranslationFilter will take over.
You can define your own entry point like this:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
if (authException != null) {
// you can check for the spefic exception here and redirect like this
response.sendRedirect("403.html");
}
}
}
You can specify this as your entry point by setting this as you entry point in the xml config file:
<http entry-point-ref="customAuthenticationEntryPoint">
...
</http>
In your specific case the PreInvocationAuthorizationAdviceVoter will be invoked by whatever AccessDecisionManager you specify in your configuration (typically it is one of the following: AffirmativeBased, ConsensusBased, or UnanimousBased). You will see that these Voters throw the AccessDeniedException which you can specifically catch and handle in your entry point.
Grant
I want to display custom error message in jsp for spring security authentication exceptions.
For wrong username or password,
spring displays : Bad credentials
what I need : Username/Password entered is incorrect.
For user is disabled,
spring displays : User is disabled
what I need : Your account is diabled, please contact administrator.
Do I need to override AuthenticationProcessingFilter just for this ? or else can I do something in jsp itself to find the authentication exception key and display different message
Redefine the properties in messages.properties inside spring security jar. For example add to the classpath myMessages.properties and add a message source to the context:
AbstractUserDetailsAuthenticationProvider.badCredentials=Username/Password entered is incorrect.
AbstractUserDetailsAuthenticationProvider.disabled=Your account is diabled, please contact administrator.
At Salvin Francis:
Add myMessages.properties to the WAR file inside WEB-INF/classes.
Add this bean to spring context config file
Message Source Bean
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>myMessages</value>
</list>
</property>
</bean>
After adding the "messageSource" bean, I had problems to get the Error Message work with the CookieLocaleResolver because the DispatcherServlet (which does use this for your application automatically) is invoked after the Security.
See: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#localization
My Solution was a custom Filter which sets the LocalContextHolder:
public class LocaleContextFilter extends OncePerRequestFilter {
private LocaleResolver localeResolver;
public void setLocaleResolver(LocaleResolver localeResolver) {
this.localeResolver = localeResolver;
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// store Local into ThreadLocale
if (this.localeResolver != null) {
final Locale locale = this.localeResolver.resolveLocale(request);
LocaleContextHolder.setLocale(locale);
}
try {
filterChain.doFilter(request, response);
} finally {
LocaleContextHolder.resetLocaleContext();
}
}
}
And the Spring Security Context configuration:
<http use-expressions="true">
<custom-filter ref="localeContextFilter" after="FIRST" />
.....
</http>
<beans:bean id="localeContextFilter" class="at.telekom.ppp.util.opce.fe.interceptor.LocaleContextFilter" >
<beans:property name="localeResolver" ref="localeResolver" /><!-- e.g.: CookieLocaleResolver -->
</beans:bean>
I hope this helps others which has this problem.
Here is a JSP EL fix for this. More of a hack than an elegant solution, but gets the job done quick and dirty. Caveat- this is not i18n safe! Only English.
This requires the functions tag library:
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
And the replace code:
${fn:replace(SPRING_SECURITY_LAST_EXCEPTION.message, 'Bad credentials', 'Username/Password are incorrect')}
I am new to spring, but try this at the server:
throw new BadCredentialsException("This is my custom message !!");
Of course you need a class that is an authentication provider for this to work.