Jetty RewriteHandler and contextHandler - url-rewriting

I have an application running on an embeded jetty server. I'm trying to add a write to add a RewriteHandler in order to redirect from the root of my web-application (http:///www.example.com) to (http:www.example.com/web).
I added the RewriteHandler, however I'm being redirected to http://www.example.com/home.html (or main.html, depending on if the user has signed in or not).
I actually want to be redirected to http://www.example.com/web/home.html.
How should I modify the code below, in order for that to happen:
ServletContextHandler servletHandler =
new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletHandler.addServlet(ServletContainer.class, "/*");
String staticPath = StartServer.class.getResource("/resources/www-static/").toExternalForm();
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setBaseResource(Resource.newResource(staticPath));
resourceHandler.setWelcomeFiles(new String[] { "home.html" });
ContextHandler staticHandler = new ContextHandler("/web");
staticHandler.setHandler(resourceHandler);
RewriteHandler rewriteHandler = new RewriteHandler();
rewriteHandler.setRewriteRequestURI(true);
rewriteHandler.setRewritePathInfo(false);
RewritePatternRule redirect = new RewritePatternRule();
redirect.setPattern("^/?$");
redirect.setReplacement("/web");
rewriteHandler.addRule(redirect);
rewriteHandler.setHandler(resourceHandler);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { servletHandler, staticHandler, rewriteHandler });
jetty.setHandler(handlers);

Put RewriteHandler first.
And don't mix ServletContextHandler and ResourceHandler.
See https://stackoverflow.com/a/28419106/775715 and https://stackoverflow.com/a/34277268/775715

Related

Attaching zip file is not working in WEB API, but works via POSTMAN

I have an .net core WEB API method that needs to call another external API (java) which expects .zip file. When try to access the external API via Postman by attaching the file, it is working fine (getting expected response). However when i pass the same parameters via my WEB API code, it is throwing 403-Forbidden error.
Please let me know if i am missing anything....
Thanks in advance!!!
request-header
request-body-file-attached
response-403-error
API code: for connecting to api:
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("pane", "forward");
parameters.Add("forward_path", "/store/execute");
parameters.Add("csrf", "1996fe6b2d0c97a8a0db725a10432d83");
parameters.Add("data_format", "binary");
newContent = new FormUrlEncodedContent(parameters);
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent con;// = new StringContent("file_name");
//form.Add(con, "file_name");
form.Add(newContent);
var str = new FileStream("D:\\dummy\\xmlstore.zip", FileMode.Open);
con = new StreamContent(str);
con.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "file_name",
FileName = "xmlstore.zip"
};
con.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
form.Add(con);
client.DefaultRequestHeaders.Add("Cookie", "JSESSIONID=05DEB277E294CBF73288F2E24682C7EE;");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("user-agent", "1"));
var resp = client.PostAsync("java-api", con).Result;

GetExternalLoginInfoAsync returns null dotnet core 2.0

I'm trying to setup Facebook authentication with dot-net core 2.0, but in my ExternalLoginCallbackAsync method, I'm always getting null as a response I have followed the documentation and so far this is what I've done:
in my ConfigureServices in the startup file:
services.AddAuthentication(
options => options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme);
services.AddAuthentication().AddFacebook(
f => {
f.AppId = Configuration["facebook-app-id"];
f.AppSecret = Configuration["facebook-app-secret"];
});
in my login controller:
public IActionResult ExternalLogin(string provider)
{
var authProperties = new AuthenticationProperties
{
RedirectUri = Url.Action("ExternalLoginCallbackAsync", "Login")
};
return Challenge(authProperties,provider);
}
in my ExternalLoginCallbackAsync method
when I do
var info = await _signInManager.GetExternalLoginInfoAsync();
any hint why am I always getting null?
thanks
I looked at the SignInManager code as Lasse Vabe Rolstad suggested and for me, a key was missing in the auth properties so I had to add it manually like this:
var authProperties = new AuthenticationProperties
{
RedirectUri = Url.Action("ExternalLoginCallbackAsync", "Login"),
Items = { new KeyValuePair<string, string>("LoginProvider",provider) }
};
In my case, I had to enable SSL, once I enabled SSL it returned info correctly, to enable SSL, right click on the project --> properties --> Debug --> check (Enable SSL) in web server strings section. I'm using core 3.0

Implementing a dynamic OAuthBearerServerOptions AccessTokenExpireTimeSpan value from data store

The context of this post involves ASP.NET Web API 2.2 + OWIN
The environment is a single application with both OWIN server and Web Api.
Background:
In the Startup class, one must specify OAuthBearerServerOptions which is supplied to the OAuthBearerAuthenticationProvider. These options are created during the start up of the OWIN server. On the OAuthBearerServerOptions, I must specify the AccessTokenExpireTimeSpan so that I can ensure expiry of tokens.
The Issue
I must be able to dynamically specify the Expiration time span on a per authentication request basis. I am unsure if this can be done and was wondering:
Can it be done?
If yes; at which point could I perform this look up and assignment of the expiration?
Content of start up config:
var config = new HttpConfiguration();
WebApiConfig.Register(config);
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/OAuth"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(**THIS NEEDS TO BE DYNAMIC**)),
Provider = new AuthorizationServerProvider()
};
//STOP!!!!!!!!
//DO NOT CHANGE THE ORDER OF THE BELOW app.Use statements!!!!!
//Token Generation
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); //this MUST come before oauth registration
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
Provider = new BearerProvider()
});
app.UseAutofacMiddleware(container); //this MUST come before UseAutofacWebApi
app.UseAutofacWebApi(config);//this MUST come before app.UseWebApi
app.UseWebApi(config);
I started messing with the BearerProvider class (see app.UseOAuthBearerAuthentication above for where I use this class) and in specific, the ValidateIdentity method, but wasn't sure if that was the proper point in the auth workflow to set this value. It seemed appropriate, but I seek validation of my position.
public class BearerProvider : OAuthBearerAuthenticationProvider
{
public override async Task RequestToken(OAuthRequestTokenContext context)
{
await base.RequestToken(context);
//No token? attempt to retrieve from query string
if (String.IsNullOrEmpty(context.Token))
{
context.Token = context.Request.Query.Get("access_token");
}
}
public override Task ValidateIdentity(OAuthValidateIdentityContext context)
{
//context.Ticket.Properties.ExpiresUtc= //SOME DB CALL TO FIND OUT EXPIRE VALUE..IS THIS PROPER?
return base.ValidateIdentity(context);
}
}
Thanks in advance!
Setting context.Options.AccessTokenExpireTimeSpan will actually change the global value, and affect all requests, that won't work for the original requirement.
The right place is the TokenEndpoint method.
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
...
if (someCondition)
{
context.Properties.ExpiresUtc = GetExpirationDateFromDB();
}
...
}
So I was in the wrong spot entirely. What I ended up having to do was to use my custom OAuthorizationServerProvider and in the overridden GrantResourceOwnerCredentials method in that custom class, I was able to set the timeout value by accessing the...
context.Options.AccessTokenExpireTimeSpan
property.
<!-- language: c# -->
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//DO STUFF
var expireValue=GetTimeOutFromSomeplace();
context.Options.AccessTokenExpireTimeSpan = expireValue;
//DO OTHER TOKEN STUFF
}
}

Android ksoap2 i:type suppression

I am trying to figure out how to suppress the i:type tag in the xml output generated by the ksoap2 library. I have tried the answers given in other posts but they have not worked. Does anyone have any ideas?
public static SoapObject createRequest() {
SoapObject method = new SoapObject(WS_NAMESPACE, WS_METHOD_NAME);
SoapObject request = new SoapObject("", "Request");
//Create source credentials object
SoapObject sourceCredentials = new SoapObject("", "SourceCredentials");
PropertyInfo sourceNameProp = new PropertyInfo();
//sourceNameProp.setNamespace(WS_NAMESPACE);
sourceNameProp.setName("SourceName");
sourceNameProp.setValue(SOURCENAME);
PropertyInfo passwordProp = new PropertyInfo();
//passwordProp.setNamespace(WS_NAMESPACE);
passwordProp.setName("Password");
passwordProp.setValue(PASSWORD);
sourceCredentials.addProperty(sourceNameProp);
sourceCredentials.addProperty(passwordProp);
SoapObject siteIds = new SoapObject("","SiteIDs");
PropertyInfo siteIDProp = new PropertyInfo();
//siteIDProp.setNamespace(WS_NAMESPACE);
siteIDProp.setName("int");
siteIDProp.setValue(SITE_IDS);
siteIds.addProperty(siteIDProp);
sourceCredentials.addSoapObject(siteIds);
request.addSoapObject(sourceCredentials);
PropertyInfo xMLDetailProp = new PropertyInfo();
//xMLDetailProp.setNamespace(WS_NAMESPACE);
xMLDetailProp.setName("XMLDetail");
xMLDetailProp.setValue("Full");
PropertyInfo pageSizeProp = new PropertyInfo();
//pageSizeProp.setNamespace(WS_NAMESPACE);
pageSizeProp.setName("PageSize");
pageSizeProp.setValue("10");
PropertyInfo curPageProp = new PropertyInfo();
//curPageProp.setNamespace(WS_NAMESPACE);
curPageProp.setName("CurrentPageIndex");
curPageProp.setValue("0");
request.addProperty(xMLDetailProp);
request.addProperty(pageSizeProp);
request.addProperty(curPageProp);
method.addSoapObject(request);
return method;
}
Then we create the envelope using code snippet below:
// 1. Create SOAP Envelope using the request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.implicitTypes = true;
envelope.setAddAdornments(false);
envelope.setOutputSoapObject(parameter);
// 2. Create a HTTP Transport object to send the web service request
HttpTransportSE httpTransport = new HttpTransportSE(WSDL_URL);
httpTransport.debug = true; // allows capture of raw request/response in Logcat
// 3. Make the web service invocation
httpTransport.call(WS_NAMESPACE + "/" + WS_METHOD_NAME, envelope);
Output XML is below. Problem is the web service does not like the i:type fields on the Request and SourceCredentials nodes and I can't figure out how to suppress them. Can someone please help? Thanks.
<v:Envelope xmlns:i="http://www.w3.org/1999/XMLSchema-instance" xmlns:d="http://www.w3.org/1999/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"><v:Header />
<v:Body>
<GetLocations xmlns="http://clients.mindbodyonline.com/api/0_5">
<Request i:type=":Request">
<SourceCredentials i:type=":SourceCredentials">
<SourceName i:type="d:string">PilatesonCollins</SourceName>
<Password i:type="d:string">XGn2PaLeRoD8qoDtrZfODu8j71c=</Password>
<SiteIDs i:type=":SiteIDs">
<int i:type="d:int">25755</int>
</SiteIDs>
</SourceCredentials>
<XMLDetail i:type="d:string">Full</XMLDetail>
<PageSize i:type="d:string">10</PageSize>
<CurrentPageIndex i:type="d:string">0</CurrentPageIndex>
</Request>
</GetLocations>
</v:Body>
</v:Envelope>
You should set right type for each PropertyInfo:
propertyInfo.setType(value.getClass());.
In conjanction with envelope.implicitTypes = true; it will have effect.

How to prevent caching of static files in embedded Jetty instance?

I want to prevent my CSSs from being cached on the browser side. How can I do it in embedded Jetty instance?
If I were using xml configuration file, I would add lines like:
<init-param>
<param-name>cacheControl</param-name>
<param-value>max-age=0,public</param-value>
</init-param>
How I can turn that into the code?
Right now I start Jetty this way:
BasicConfigurator.configure();
Server server = new Server();
SocketConnector connector = new SocketConnector();
// Set some timeout options to make debugging easier.
// 1 hour
connector.setMaxIdleTime( 1000 * 60 * 60 );
connector.setSoLingerTime( -1 );
connector.setPort( 8081 );
server.setConnectors( new Connector[] { connector } );
WebAppContext bb = new WebAppContext();
bb.setServer( server );
bb.setContextPath( "/" );
bb.setWar( "src/webapp" );
server.addHandler( bb );
I think I should search setControlCache somewhere in the WebAppContext area of responsibility.
Any advices on this?
I normally use a ServletHolder, like this:
WebAppContext context = new WebAppContext();
ServletHolder servletHolder = new ServletHolder(MyServlet.class);
servletHolder.setInitParameter("cacheControl","max-age=0,public");
context.addServlet(servletHolder, "myservletpath");
While this does not exactly match your code you should be able to figure it out from there ?
Duh, how to do just the opposite How to configure cache for static resources in web.xml for Jetty??
And here's just a working code with no need to figure out, guess and try. It's provided with respect to code in question and jetty 6. For jetty 7 and higher need to change Context to ServletContextHandler.
BasicConfigurator.configure();
Server server = new Server();
SocketConnector connector = new SocketConnector();
// Set some timeout options to make debugging easier.
// 1 hour
connector.setMaxIdleTime( 1000 * 60 * 60 );
connector.setSoLingerTime( -1 );
connector.setPort( 8081 );
server.setConnectors( new Connector[] { connector } );
//--- The difference with code in question starts here
DefaultServlet defaultServlet = new DefaultServlet();
ServletHolder holder = new ServletHolder(defaultServlet);
holder.setInitParameter("useFileMappedBuffer", "false");
holder.setInitParameter("cacheControl", "max-age=0, public");
Context bb = new Context();
bb.setResourceBase("src/webapp");
bb.addServlet(holder, "/");
//--- Done. Caching is off!
server.addHandler( bb );
// Run server as usual with server.run();
My sample also sets useFileMappedBuffer to false which is needed for not blocking files on a disk if you are developing on Windows by any reason.
I use resourceHandler for static contents.
Here's a code working fine on Jetty 9.
ResourceHandler rh = new ResourceHandler();
rh.setResourceBase([your_resource_base_dir]);
rh.setCacheControl("no-store,no-cache,must-revalidate");

Resources