jsf secure tranport mechanism - jsf

i have been working on a simple jsf secure transport mechanism where the configured https constraints is set to confidential in web.xml.Now, what i wanted to do was to select a particular page for secure transport. i have a login page that takes me to another page.Login page takes a user name and password and should transport it over secure layer to an ejb that verifies its authenticity before it displays the requested page.Now when i use a url pattern like /faces/pageToView.xhtml for the requested page in web.xml, i get a funny behaviour i dont really understand.First, when i login, my pageToView.xhtml displays without the https and when i click to go to another pageToView2.xhtml my first pageToView.xhtml redisplays with https. Not only that all other pages i navigate to displays https even though i had not configure them for secure transport. I need to know the right way to configure secure transport behaviour for a particular page. Thanks in advance.

The way it seems to be is that when you go to https, and you're generally going to do this on the login page, you stay on https. It seemed to me to be a big overhead for an application with limited security requirements but on looking into it the consensus is that the big risk is session hijacking. So if you had 2 secure pages login & shopping and all the other pages don't use ssl they'll be sending the session cookie over the air/wire in the clear and the cookie could be sniffed.
I think that if you have an apache web server fronting your application server you have a lot more options such as using https between the client browser and apache for certain pages, but using http between apache and the app server. I'm fairly sure that you can do this but I'm no expert and haven't tried it.
When I was looking into this some time ago I came across this filter written by one of the Glassfish team which is supposed to downshift from https - http. My recollection is that having downshifted everything just stopped working, when used in conjunction with container security.
With a few tweaks you could adapt this to your environment, in this example the main.xhtml file is the welcome-file from web.xml, the idea being that this would be the page loaded on successful login so the earliest point at which to downshift from https - http. You'd need to uncomment #WebServlet, use your own logging in place of Log.log() and check any url/pathnames.
Before spending any time on this please remember that I could never get this to work and the the recommendation is to take the hit and use https all the time.
package uk.co.sportquest.jsfbeans.helper;
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU General
* Public License Version 2 only ("GPL") or the Common Development and
* Distribution License("CDDL") (collectively, the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy of the
* License at https://glassfish.dev.java.net/public/CDDL+GPL.html or
* glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year] [name of copyright
* owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or only
* the GPL Version 2, indicate your decision by adding "[Contributor] elects to
* include this software in this distribution under the [CDDL or GPL Version 2]
* license." If you don't indicate a single choice of license, a recipient has
* the option to distribute your version of this file under either the CDDL, the
* GPL Version 2 or to extend the choice of license to its licensees as provided
* above. However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is made
* subject to such option by the copyright holder.
*/
import java.io.*;
import java.util.*;
import java.security.*;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.security.jacc.*;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.*;
import uk.co.sportquest.general.Log;
/**
* Filter that downshifts from https to http if the given request came in over
* https, but the target resource does not require any confidentiality
* protection.
*
* #author jluehe
* #author monzillo
*/
//#WebFilter(filterName = "CacheFilterStatic", urlPatterns = {"/faces/secure/main.xhtml"},
// dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.ERROR, DispatcherType.REQUEST, DispatcherType.INCLUDE})
public class MyFilter implements Filter {
private static final CodeSource cs =
new CodeSource(null, (java.security.cert.Certificate[]) null);
private static final ProtectionDomain pd =
new ProtectionDomain(cs, null, null, null);
// private static final Policy policy = Policy.getPolicy();
private static final Policy policy = Policy.getPolicy();
private static final String httpPort = "8080";
#Override
public void init(javax.servlet.FilterConfig filterConfig)
throws ServletException {
//httpPort = filterConfig.getInitParameter("httpPort");
}
#Override
#SuppressWarnings("static-access")
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain filterChain)
throws IOException, ServletException {
if (req.isSecure()) {
HttpServletRequest httpReq = (HttpServletRequest) req;
Permission p = new WebUserDataPermission(httpReq);
p = new WebUserDataPermission(p.getName(), httpReq.getMethod());
//SQLog.log("Filter: " + httpReq.getRequestURI());
boolean isTransportProtected = policy.implies(pd, p) ? false : true;
Log.log();
if (!isTransportProtected) {
// Downshift from https to http, by redirecting to the
// target resource using http
String redirectUrl = "http://" + req.getServerName() + ":"
+ httpPort + httpReq.getRequestURI();
String queryString = httpReq.getQueryString();
if (queryString != null) {
redirectUrl += "?" + queryString;
}
//redirectUrl = "http://localhost:8080/SportQuest/faces/secure/main.xhtml";
Log.log("url: " + redirectUrl);
((HttpServletResponse) res).sendRedirect(redirectUrl);
} else {
// Perform normal request processing
Log.log("normal");
filterChain.doFilter(req, res);
}
} else {
// Perform normal request processing
Log.log("even more normal");
filterChain.doFilter(req, res);
}
}
#Override
public void destroy() {
// Do nothing
}
}

Related

Is there an API call in AWS Elastic Beanstalk to have a list of running hosts? (with IPs)

The title really says it all. I need each instance running to be aware of what the other instances are, including their IP addresses. Is there an EB API call to do that? Or maybe a more generic way in AWS?
The AWS Elastic Beanstalk SDK exposes methods that provide details about both the Environment and Applications. (Not clear what you mean by I need each instance running to be aware of what the other instances are)
Anyhow -- you can get a list of applications and get details about those EB apps. For example, you can get the status (an EB app that is running will have a status value Ready) and the app URL (not the IP). SO you can get at the details you are looking for with the SDK.
Running this code returns details that you see the AWS Management Console -- such as:
The application name is VideoAnalyzer
The Environment ARN is arn:aws:elasticbeanstalk:us-east-1:xxxxxx047983:environment/VideoAnalyzer/Videoanalyzer-env
The Endpoint URL is awseb-AWSEB-xxxxxxY1BQF02-xxxx6689.us-east-1.elb.amazonaws.com
The status is Ready
I will show you the code in Java SDK v2.
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.elasticbeanstalk.ElasticBeanstalkClient;
import software.amazon.awssdk.services.elasticbeanstalk.model.DescribeApplicationsResponse;
import software.amazon.awssdk.services.elasticbeanstalk.model.ApplicationDescription;
import software.amazon.awssdk.services.elasticbeanstalk.model.DescribeEnvironmentsRequest;
import software.amazon.awssdk.services.elasticbeanstalk.model.DescribeEnvironmentsResponse;
import software.amazon.awssdk.services.elasticbeanstalk.model.EnvironmentDescription;
import software.amazon.awssdk.services.elasticbeanstalk.model.ElasticBeanstalkException;
import java.util.List;
//snippet-end:[eb.java2.describe_app.import]
/**
* Before running this Java V2 code example, set up your development environment, including your credentials.
*
* For more information, see the following documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class DescribeApplications {
public static void main(String[] args) {
Region region = Region.US_EAST_1;
ElasticBeanstalkClient beanstalkClient = ElasticBeanstalkClient.builder()
.region(region)
.build();
describeApps(beanstalkClient);
}
//snippet-start:[eb.java2.describe_app.main]
public static void describeApps(ElasticBeanstalkClient beanstalkClient) {
try {
DescribeApplicationsResponse applicationsResponse = beanstalkClient.describeApplications();
List<ApplicationDescription> apps = applicationsResponse.applications();
for (ApplicationDescription app: apps) {
System.out.println("The application name is "+app.applicationName());
DescribeEnvironmentsRequest desRequest = DescribeEnvironmentsRequest.builder()
.applicationName(app.applicationName())
.build();
DescribeEnvironmentsResponse res = beanstalkClient.describeEnvironments(desRequest) ;
List<EnvironmentDescription> envDesc = res.environments();
for (EnvironmentDescription desc: envDesc) {
System.out.println("The Environment ARN is "+desc.environmentArn());
System.out.println("The Endpoint URL is "+ desc.endpointURL());
System.out.println("The status is "+ desc.status());
}
}
} catch (ElasticBeanstalkException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
//snippet-end:[eb.java2.describe_app.main]
}

What is the DSL version of int-jms:inbound-gateway request-destination

I am trying to create an app that will listen to JMS queue, process message and sends response to another JMS queue. As I understood the docs I can use JMS inbound gateway and some handler to process the request, something like this:
IntegrationFlows.from(Jms.inboundGateway(connectionFactory).defaultReplyQueueName(responseQueue)).handle(handler).get();
However I don't know how to set the input JMS queue via DSL. I found that via XML it can be done as following:
<int-jms:inbound-gateway id="jmsInGateway"
request-destination="inQueue"
request-channel="exampleChannel"/>
Sadly Jms.inboundGateway() does not allow to set request destination. How can I set it?
There are these two options for destination on that Spec:
/**
* #param destination the destination
* #return the spec.
* #see JmsListenerContainerSpec#destination(Destination)
*/
public JmsInboundGatewayListenerContainerSpec<S, C> destination(Destination destination) {
this.spec.destination(destination);
return _this();
}
/**
* #param destinationName the destinationName
* #return the spec.
* #see JmsListenerContainerSpec#destination(String)
*/
public JmsInboundGatewayListenerContainerSpec<S, C> destination(String destinationName) {
this.spec.destination(destinationName);
return _this();
}
So, your code snippet works for me like this:
return IntegrationFlows.from(
Jms.inboundGateway(connectionFactory)
.destination("inQueue")
.defaultReplyQueueName(responseQueue))
.handle(handler)
.get();
I'm not sure why is that not visible for you...
On the other hand I see your point. It is probably better to name that option as a requestDestination for consistency with the replyQueueName and the same option in the XML DSL. Feel free to raise a GH issue or even provide a contribution on the matter deprecating an existing destination option!

How to redirect to a dynamic route after user register for the first time in Laravel 7

I am new to Laravel and using Laravel 7, I want to ask that, when a new user register for the first time a verification email is sent to his/her inbox and when he verifies it, must be redirected to a route like the edit profile page to complete the registration process... something like:
route('user/ . $user->id . / edit');
Im not sure if I should edit this page, if so how? because it redirects to the HOME
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}
You can change it from app/Providers/RouteServiceProvider.php :
public const HOME = '/home';
to,
public const HOME = '/dashboard';
Then it will throw you to the /dashboard

Is there a way to check and clean Certificate Revocation List cache for ASP.NET Core application that is dockerized and run under the Linux?

We need to implement checks of client certificate validity in our ASP.NET Core 2.X application that is dockerized and run under Linux. In particular, we are interested in revocation status of certificates. Such validation was implemented by using X509Chain and it works as expected.
var chain = new X509Chain();
var chainPolicy = new X509ChainPolicy
{
RevocationMode = X509RevocationMode.Online,
RevocationFlag = X509RevocationFlag.EntireChain
};
chain.ChainPolicy = chainPolicy;
...
Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
....
However, we have requirements regarding the expiration time of CRL cache for our application. It looks like Linux (I assume it is debian for mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim image) caches CRLs by default - first request last for ~150ms and the following requests are handled almost in no time (unfortunately I cannot find available information to confirm this observation).
What is default time for CRL cache in Linux (debian)? Is it possible to change it? Is there a way to check list of the cached CRL?
Is possible to clean CRL cache like in Windows?
certutil -urlcache * delete
Linux certificate util dirmngr seems to be is not a part of the mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim base image for ASP.NET Core 2.2 applications.
As it is .net Core, which is open source, have you looked up the sources at github. There you'lkl find a call to the CrlCache which shows where data is stored:
namespace Internal.Cryptography.Pal
{
internal static class CrlCache
{
private static readonly string s_crlDir =
PersistedFiles.GetUserFeatureDirectory(
X509Persistence.CryptographyFeatureName,
X509Persistence.CrlsSubFeatureName);
internal static class X509Persistence
{
internal const string CryptographyFeatureName = "cryptography";
internal const string X509StoresSubFeatureName = "x509stores";
internal const string CrlsSubFeatureName = "crls";
internal const string OcspSubFeatureName = "ocsp";
}
...
internal const string TopLevelDirectory = "dotnet";
internal const string TopLevelHiddenDirectory = "." + TopLevelDirectory;
internal const string SecondLevelDirectory = "corefx";
...
internal static string GetUserFeatureDirectory(params string[] featurePathParts)
{
Debug.Assert(featurePathParts != null);
Debug.Assert(featurePathParts.Length > 0);
if (s_userProductDirectory == null)
{
EnsureUserDirectories();
}
return Path.Combine(s_userProductDirectory, Path.Combine(featurePathParts));
}
private static void EnsureUserDirectories()
{
string userHomeDirectory = GetHomeDirectory();
if (string.IsNullOrEmpty(userHomeDirectory))
{
throw new InvalidOperationException(SR.PersistedFiles_NoHomeDirectory);
}
s_userProductDirectory = Path.Combine(
userHomeDirectory,
TopLevelHiddenDirectory,
SecondLevelDirectory);
}
internal static string GetHomeDirectory()
{
// First try to get the user's home directory from the HOME environment variable.
// This should work in most cases.
string userHomeDirectory = Environment.GetEnvironmentVariable("HOME");
So the path should be $HOME/.dotnet/corefx/cryptography/crls

MVC Form based Spring Security login?

I have an application that uses Spring Security to control access to pages, to manage user roles (GrantedAuthority) and for ACL. The application uses the standard UsernamePasswordAuthenticationFilter that intercepts requests to /j_spring_security_check (with j_username and j_password request parameters), and using a ProviderManager it authenticates the user and on success stores it in the SecurityContextHolder.
The above is configured in the security context, using a customized UserDetailsService:
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref='myUserDetailsService'/>
</authentication-manager>
The above approach in my case is not optimal, for the following reasons:
Adding a captcha requires extra filters
In order to customize the login logic, I need to replace the AuthenticationProvider as well
showing errors in the login form is complex, since I cannot use Spring MVC's forms
My idea is to remove the interceptor based login and put all the logic inside a Spring 3 MVC controller. The pseudo-code is as following:
RequestMapping(value="/login/", method = RequestMethod.POST)
public String attemptLogin(HttpServletRequest request, HttpServletResponse response,
#ModelAttribute("login") LoginCmd login, Model model) {
// validate command (username, password, captcha)
// ...
// load user from DB
User user = userService.loadUserByUsername(login.getUsername());
// extra logic (check number of failed logins + other stuff)
// ...
// In case everything is fine, create a spring security User
/* Instead of creating the user, read it from DB */
org.springframework.security.core.userdetails.User authUser =
new org.springframework.security.core.userdetails.User(
login.getUsername() /*username*/,
login.getPassword() /*password*/,
true /*enabled*/,
true /*accountNonExpired */,
true /*credentialsNonExpired */,
true /*accountNonLocked*/,
new ArrayList<GrantedAuthority>() /*authorities*/
);
// build the AuthenticationToken
UsernamePasswordAuthenticationToken authResult =
new UsernamePasswordAuthenticationToken(authUser, login.getPassword(),
authUser.getAuthorities());
// use WebAuthenticationDetailsSource do build details
authResult.setDetails(detailsSource.buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authResult);
return SUCCESS_VIEW;
}
Do you see any problem with the solution here above? Is setting the authentication inside the SecurityContextHolder enough? Am I missing something?
Comments and suggestions are welcome ;-)
Thanks a lot to everyone
Andrea
I went through the Spring Security code, and on successful authentication also the original code just stores the Authentication object in the SecurityContextHolder, nothing else is done.
For example, in class AbstractAuthenticationProcessingFilter (which is used by the standard login intercepting requests to /j_spring_security_check) does that:
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
Authentication authResult) throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
successHandler.onAuthenticationSuccess(request, response, authResult);
}
I implemented this on my application and everything works fine.

Resources