This question already has answers here:
i18n with UTF-8 encoded properties files in JSF 2.0 application
(3 answers)
Closed 7 years ago.
In my Application I made it to have it in two languages. English and French.
In English, its all right. But while Reading the Properties file for French Language it ends up showing mojibake.
I have in my properties file like this:
example.french.char=é
but it does not show properly in the application. I am viewing my app in Windows. I dont want to replace the French characters by Unicode characters. I want them to be read from properties file as they normally appear.
How can I make it work?
Please suggest. Can I make it happen to view the French Characters without using Unicodes?
My properties file is encoded in UTF-8.
Please suggest!
I tried the following too..
public class CharacterEncodingFilter implements Filter{
private FilterConfig config;
#Override
public void destroy() {
setConfig(null);
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filter) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
filter.doFilter(request, response);
}
#Override
public void init(FilterConfig config) throws ServletException {
setConfig(config);
}
public FilterConfig getConfig() {
return config;
}
public void setConfig(FilterConfig config) {
this.config = config;
}
}
and added this in web.xml
<filter>
<filter-name>charEncoding_Filter</filter-name>
<filter-class>com.edfx.tum.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>charEncoding_Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
but still it shows mojibake.
Did you try to set request/response encoding type to UTF-8, with servlet filter class.
Here is an example:
import java.io.IOException;
import java.io.Serializable;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SetCharacterEncodingFilter implements Filter, Serializable {
private static final long serialVersionUID = -4518853484989127891L;
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig arg0) throws ServletException {
}
}
Then you register the filter in web.xml
<filter>
<filter-name>UTF8Charset</filter-name>
<filter-class>your.package.name.SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UTF8CharSet</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
If your properties file is in UTF-8 you may have an issue as it should be in ISO-8859-1 in the load(InputStream). You will have to load your properties using the load(Reader) where you specify the encoding when constructing the reader.
Related
I am working a project that leverages Spring Security Shiro. I would like to configure the application to have 2 different login forms with 2 different authentication success urls. What is the best way to perform this? I looked at the documentation but have not seen any solutions.
Thank you in advance for your help.
The easiest and the best way it's extending two separate WebSecurityConfigurerAdapter and creating there two different configuration (two login page and two authentication success urls):
#Configuration
#Order(94)
public class WebSecurityConf1 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/first-resources**").formLogin().successForwardUrl();
}
}
and
#Configuration
#Order(95)
public class WebSecurityConf2 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/second-resources**").formLogin().successForwardUrl();
}
}
Note that WebSecurityConf1 will be applied when .antMatcher("/first-resources**") is satisfied and the same for WebSecurityConf2. Also, configuration between WebSecurityConf1 and WebSecurityConf2 independent.
The simple way was to override the AuthenticationSuccessHandler with a custom one.
First create your success handler, my checks to see if the user is an admin user.
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
import org.springframework.security.core.Authentication
import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession
class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
def requestCache
boolean administrator = false
#Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
println administrator
if(administrator){
return "/admin"
} else {
return super.determineTargetUrl(request, response)
}
}
#Override
public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response,
final Authentication authentication) throws ServletException, IOException {
try {
checkSetAdministratorUser(authentication)
handle(request, response, authentication)
super.clearAuthenticationAttributes(request)
}catch(Exception e){
e.printStackTrace()
} finally {
// always remove the saved request
requestCache.removeRequest(request, response)
}
}
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String targetUrl = determineTargetUrl(request, response)
if (response.isCommitted()) {
logger.debug("Response has already been committed. Unable to redirect to " + targetUrl)
return
}
redirectStrategy.sendRedirect(request, response, targetUrl)
}
def checkSetAdministratorUser(authentication){
authentication.authorities.each(){ authority ->
if(authority.authority == "ROLE_ADMIN")administrator = true
}
}
}
Then I had to define the success handler in the beans section of resources.groovy
beans = {
authenticationSuccessHandler(CustomAuthenticationSuccessHandler) {
requestCache = ref('requestCache')
redirectStrategy = ref('redirectStrategy')
}
}
Then I was good to go. It worked well for my scenario.
Thanks: https://groggyman.com/2015/04/05/custom-authentication-success-handler-with-grails-and-spring-security/
I am using Spring Security and Spring Oauth2 and JWT in my API project
The default API in order to login which Spring oauth 2 provided, is /oauth/token
This API always adds "Strict-Transport-Security: max-age=31536000 ; includeSubDomains" header to the response.
But I don't want this in my situation. And I have removed HSTS with the below source code.
#EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.httpStrictTransportSecurity().disable();
}
}
With above code, APIs I defined is removed HSTS in header. But the default API /oauth/token still return HSTS in header.
Is there any way to do this ?
Please help.
Thanks,
Tin
I just ran into the same issue.
The best solution I found is writing a filter that prevents others from setting the HSTS header in general.
#Component
#Order(value = Ordered.HIGHEST_PRECEDENCE)
public class HstsHeaderPreventionFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
public void setHeader(String name, String value) {
if (!name.equalsIgnoreCase("Strict-Transport-Security")) {
super.setHeader(name, value);
}
}
});
}
#Override
public void destroy() {
}
}
I have a spring-boot application with spring-security and dropwizard metrics. It uses Angularjs as a frontend. Authentication is done using separate login.html page with angularjs controller posting credentials to '/login' and after seccessful response routing to index.html (separate angularjs app). This all works quite well until I try to access dropwizard metrics. In this case I get a spring-security exception saying that user is anonymous (all other urls work fine).
My spring-security config:
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
#EnableWebSecurity
public class FormLoginSecurityConfigurer extends WebSecurityConfigurerAdapter {
private class AuthSuccessHandler implements AuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
}
}
private class AuthFailureHandler implements AuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login.html", "/scripts/login/**", "/libs/**", "/styles/**", "/images/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login.html").loginProcessingUrl("/login")
.usernameParameter("username").passwordParameter("password")
.successHandler(new AuthSuccessHandler())
.failureHandler(new AuthFailureHandler())
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/login.html")
.and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(CsrfHeaderFilter.csrfTokenRepository());
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}
The metrics servlet is registered in the ServletContextInitilizer:
/**
* Configuration of web application with Servlet 3.0 APIs.
*/
#Configuration
public class WebConfigurer implements ServletContextInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
initMetrics(servletContext,
EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC));
}
/**
* Initializes Metrics.
*/
private void initMetrics(ServletContext servletContext, EnumSet<DispatcherType> disps) {
log.debug("Initializing Metrics registries");
servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
metricRegistry);
servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
metricRegistry);
log.debug("Registering Metrics Filter");
FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
new InstrumentedFilter());
metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
metricsFilter.setAsyncSupported(true);
log.debug("Registering Metrics Servlet");
ServletRegistration.Dynamic metricsAdminServlet =
servletContext.addServlet("metricsServlet", new MetricsServlet());
metricsAdminServlet.addMapping("/metrics/metrics/*");
metricsAdminServlet.setAsyncSupported(true);
metricsAdminServlet.setLoadOnStartup(2);
}
}
However when I access anything under /metrics/metrics the browser prompts for basic authentication. The response has the following header WWW-Authenticate:"Basic realm="Spring"". Other resources are downloaded fine.
I'm new to this kind of applications and getting a bit frustrated :) Any help is appreciated.
Seems its all in the docs if one knows what to look for - link
The Actuator security features can be modified using external properties (management.security.*). To override the application access rules add a #Bean of type WebSecurityConfigurerAdapter and use #Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) if you don’t want to override the actuator access rules, or #Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) if you do want to override the actuator access rules.
Changed the order to ManagementServerProperties.ACCESS_OVERRIDE_ORDER and now it works.
I don't know the lifecycle of the doFilter() method in a java filter.
I am wondering if I were to set a start time in the request at the beginning of the method, is there a way or place to set a stop time in the method that would give me the total elapsed time from the beginning of the request to the time the response is given?
I've seen a doFilter() method with a finally block in it, and I was wondering if setting a stop time in the response in there would be appropriate?
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class ResponseTimerFilter implements Filter {
protected FilterConfig config;
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
chain.doFilter(request, response);
long elapsed = System.currentTimeMillis() - startTime;
String name = "servlet";
if (request instanceof HttpServletRequest) {
name = ((HttpServletRequest) request).getRequestURI();
}
config.getServletContext().log(name + " took " + elapsed + " ms");
}
}
web.xml
<filter>
<filter-name>Timing Filter</filter-name>
<filter-class>com.omh.filters.ResponseTimerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Timing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I have a CustomOpenIDAuthenticationFilter extends org.springframework.security.openid.OpenIDAuthenticationFilter. I want to define the response url after the authentication is successful, but do not know how to do it. Any help you might have would be very much appreciated.
I have the following code at the moment:
public class CustomOpenIDAuthenticationFilter extends OpenIDAuthenticationFilter{
protected static Logger logger = Logger.getLogger("service");
public CustomOpenIDAuthenticationFilter(){
super();
ProxyProperties proxyProps = new ProxyProperties();
proxyProps.setProxyHostName(PROXYNAME);
proxyProps.setProxyPort(PROXYPORT);
HttpClientFactory.setProxyProperties(proxyProps);
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
//i think the response url should be defined here.
Authentication au = super.attemptAuthentication(request, response);
return au;
}
}
Edit
Sorry for your time, i did not explain my problem correctly.
So, when my login page is sending authentication request to openid provider, the request contains a returnToUrl, where is "The URL on the Consumer site where the OpenID Provider will return the user after generating the authentication response. ". On a non-spring application, i would do
AuthRequest authRequest = manager.authenticate(discovered, returnToUrl);
My question is how could I specify this returnToUrl at my CustomOpenIDAuthenticationFilter.
To specify the returnToUrl you can override the String buildReturnToUrl(HttpServletRequest request) method. An example of making this an arbitrary URL is given below:
public class CustomOpenIDAuthenticationFilter extends OpenIDAuthenticationFilter {
...
protected String buildReturnToUrl(HttpServletRequest request) {
// this URL needs to be processed by CustomOpenIDAuthenticationFilter to validate
// the OpenID response and authenticate the user
return "https://example.com";
}
}
As the comment mentions this URL should be a URL that CustomOpenIDAuthenticationFilter will process since it is what validates the OpenID response.
This can also be achieved by creating a custom filter an place it before OPENID_FILTER
</http>
...
<custom-filter before="OPENID_FILTER" ref="myBeforeOpenIDFilter" />
</http>
<beans:bean id="myBeforeOpenIDFilter"class="com.example.provider.openid.MyBeforeOpenIdFilter" />
And below there is my implementation of this custom filter
package com.example.provider.openid;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyBeforeOpenIdFilter implements Filter{
static Logger logger = LoggerFactory.getLogger(MyBeforeOpenIdFilter.class);
static class FilteredRequest extends HttpServletRequestWrapper {
public FilteredRequest(HttpServletRequest request) {
super(request);
}
#Override
public java.lang.StringBuffer getRequestURL(){
String baseUrl = (String) super.getSession().getServletContext().getAttribute("applicationBaseUrl");
StringBuffer sb = super.getRequestURL();
int index = sb.indexOf("/j_spring_openid_security_check");
if(index != -1){
// here replace the host etc with proper value
if(baseUrl.endsWith("/")){
baseUrl = baseUrl.substring(0, baseUrl.length()-1);
}
logger.debug("Changing the getRequestURL to inject the correct host so openid login could work behind proxy");
logger.debug("Original getRequestURL: "+sb.toString());
logger.debug("Replacing the baseUrl with: "+baseUrl);
sb.replace(0, index, baseUrl);
logger.debug("New getRequestURL: "+sb.toString());
}
return sb;
}
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
//No need to init
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new FilteredRequest((HttpServletRequest) request), response);
}
#Override
public void destroy() {
//No need to destroy
}
}
In this way you can define your openid provider using the default namespace
and have the filter plugin out if you need it. In my implementation I'm taking the baseUrl from the servlet context but it can be simply hardcoded
Hope this will help someone
Cheers
Szymon