Accessing cookies in WebView2 using PowerShell - winforms

Using the working example to start a WebView2 instance in PowerShell here: WebView2 in PowerShell Winform GUI
I noticed it maintains cookies nicely between sessions, just like 'normal' Edge. In some scenario's however, manually getting and/or setting cookies could be useful. A specific scenario I'm looking at is using WebView2 session cookies to create a WebDAV connection.
I tried creating a CookieManager like so:
$cookieManager = [Microsoft.Web.WebView2.Core.CoreWebView2CookieManager]
But $cookieManager then doesn't expose any methods to set/get cookies.

You should use the CookieManager property of the CoreWebView2 to obtain the cookie manager for a corresponding CoreWebView2. It will affect all CoreWebView2s that share the same user data folder.
$coreWebView2Initialized = {
# CookieManager only available after the CoreWebView2 property has been initialized.
$cookieManager = $webview.CoreWebView2.CookieManager;
$cookie = $cookieManager.CreateCookie("name", "value", "example.com", "/");
$cookieManager.AddOrUpdateCookie($cookie);
}
$webview.add_CoreWebView2InitializationCompleted($coreWebView2Initialized);

Related

Shiro how to secure the data source password

I have been exploring Apache Shiro with Zeppelin and so far has been able to make authentication work with JdbcRealm but one thing that is not going well is giving the data source password as plain text.
Is there a way to avoid that?
My shiro.ini looks like:
[main]
dataSource = org.postgresql.ds.PGPoolingDataSource
dataSource.serverName = localhost
dataSource.databaseName = dp
dataSource.user = dp_test
dataSource.password = Password123
ps = org.apache.shiro.authc.credential.DefaultPasswordService
pm = org.apache.shiro.authc.credential.PasswordMatcher
pm.passwordService = $ps
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealmCredentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
jdbcRealm.dataSource = $dataSource
jdbcRealm.credentialsMatcher = $pm
shiro.loginUrl = /api/login
[roles]
admin = *
[urls]
/** = authc
Is there a way to avoid giving data source password as plain text
dataSource.password = Password123?
Would like to give something like:
$shiro1$SHA-256$500000$YdUEhfDpsx9KLGeyshFegQ==$m+4wcq4bJZo1HqDAGECx50LcEkRZI0zCyq99gtRqZDk=
yes, there is a way, but there will still be a password lying around somewhere due to the nature of shiro needing to know the password.
Why Hashing does not work
You posted
something like: $shiro1$SHA-256[…]
This is a hash, and thus it is not reversible. There is no way shiro could log into the datasource using this String.
Container managed datasources
The best approach I can recommend at this point is to have a container managed resource. A container is referring to a (web) application server in this case, like tomcat, OpenLiberty or Wildfly.
For your use case, try looking into the following:
extend org.apache.shiro.realm.jdbc.JdbcRealm or AuthorizingRealm
Add the JPA API to your module and inject a persistence context like so:
#PersistenceContext
EntityManager entityManager;
Override the methods
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
… to load from your managed datasource instead.
Drawbacks of this approach:
You just delegated datasource login to your container / application server. The server is still facing the same problems. E.g. with OpenLiberty, you will still need to store a master key of an encrypted (not hashed) password somewhere, and thus liberty will do exactly this.
use another configuration source
Instead of using a shiro.ini file, you could also write your own environment loader. You could request the file from an IP-restricted web service or a cryptographic hardware device.
Always a goal: restrict the environment
You should always restrict the environment.
E.g. create a user which can install, but not run your application and who cannot read the logs (called setup-user or so).
Create another user which can start the application, read but not modify configuration files and write logs, called a run-user.
Restrict access to configurations and logs for all other users on that system.
Getting involved
If you have other needs, feel welcome to discuss other solutions on the shiro mailing lists.

WPF Webbrowser using multiple sessions when open more than once

We have a WPF webbrowser on one of our detail windows. The detail window gets opened when the user clicks on a search result so there can and will be multiple detail windows open with this webbrowser embedded. The URL is pointing to a Java based application that requires a license and is configured with NTLM to authenticate users.
The first open window is fine, but if you open more the java app gives an error that all licenses are used. In IE everything is fine, you can open multiple windows of this java app and work away.
Is there something I can configure on the webbrowser to use only one session and then clear everything when you close the main window?
**Edit: Note from the Vendor of the Java app that when a browser connects the JBoss server creates a JSessionID and that every other connection from that computer should use the same JSessionID even different browsers. The WPF control is doing something else because it is creating a session for every open view.
**Edit: The initial details I put are incorrect. The view that contains the browser control is a UserControl not a window.
**Edit: If I have no sessions and launch IE/firefox etc to open the Java app I can get a license and use the app. Now that I have a session if I try to use the WebBrowser control it will try to create a new session and I will get an error about the license. If I close the view and the browser windows and try to connect again I am again prompted with a license error as if the browser control is somehow not releasing that session.
I can post the code, but I don't see how that will help as its just a straightforward xaml insertion of the control with the source value set to the web page.
Is there a way you can separate each window/browsing session into a different appdomain?
http://msdn.microsoft.com/en-us/library/system.appdomain.aspx
On exit of the window, you could throw out that appdomain and the resources used within.
You can try and manually handle initial connectivity and then use NavigateToString to render the result. Something like this:
String responseString;
HttpWebRequest request = build you request, incorporate session token, etc
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
responseString = sr.ReadToEnd();
}
browser.NavigateToString(responseString);
EDIT:
Using cookies, source:
public partial class WebBrowserControl : Form
{
private String url;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
public WebBrowserControl(String path)
{
this.url = path;
InitializeComponent();
// set cookie
InternetSetCookie(url, "JSESSIONID", Globals.ThisDocument.sessionID);
// navigate
webBrowser.Navigate(url);
}
...
}

Windows Authentication in silverlight Vs 2010

I want to implement windows Authentication in silver light, How to do that ?
There is a workaround if you are hosting your Silverlight application in an ASP.NET page.
Make sure that your website (hosting the Silverlight .xap and ASPX page) has Windows Integration security enabled, and anonymous access disabled.
Add the following to your list:
<param name="initParams" value="myCustomParam1=Foo,userId=<% System.Security.Principal.WindowsPrincipal p = System.Threading.Thread.CurrentPrincipal as System.Security.Principal.WindowsPrincipal; Response.Write(p.Identity.Name); %>" />
This will pass your username pulled from ASP.NET into your Silverlight application.
Add this line to your App.xaml.cs page, in the Application_Startup method:
// Take parameters and store them in application resources
if (e.InitParams != null)
{
foreach (var data in e.InitParams)
{
this.Resources.Add(data.Key, data.Value);
}
}
Once you have the above steps in place, you can access your value from page code behind using the following:
App.Current.Resources["userId"].ToString();
Also, as an alternative, if you run your application on an Intranet, and run it in out-of-browser mode with elevated security, this is all much easier. You can access the Windows API using this:
if (Application.Current.HasElevatedPermissions)
{
using (dynamic wshNetwork = AutomationFactory.CreateObject("WScript.Network"))
{
return (wshNetwork.UserName);
}
}
As far as I know it's not possible to use Windows Authentication "directly" in Silverlight (at least with a self-hosted WCF service -maybe with IIS there is some support?).
An acceptable way to accomplish this in my opinion is to pass username/password to your server and there you query the Active Directory using an LDAP library. Make sure to use SSL for your service calls otherwise the credentials will travel in clear over the wire.

Silverlight or browser losing cookies on hyperlinked windows?

Am using Silverlight 4 hosted in an ASP.NET MVC page, e.g. http://test.example.com/main. I make a call to the server from Silverlight using WCF and get some values back. One of these values I write as a cookie using:
HtmlPage.Document.SetProperty("cookie", newCookie);
I can then view the cookie text using:
MessageBox.Show(HtmlPage.Document.Cookies);
I can see various cookies, including the one I just created, so looks like it was created ok.
From within the SL app, I display some hyperlinks. When the user clicks on this it will display the link in a new browser window. The links go to the same domain, e.g. http://test.example.com/viewdoc?1233
The new cookie that was created is not being passed in the request. The other cookies that were originally there are being passed. I don't see how its a crossdomain policy issue since they are going to the same domain. It doesn't matter what browser I use (Safari, Firefox, IE8, IE6), they all exhibit the same problem, so it doesn't seem to be an IE8 issue that I saw on other similar issues.
So where is my cookie going?
Verify that the path property of the cookie is not set to certain page only:
The path parameter is potentially the
most useful of the 4 optional cookie
settings. It sets the URL path the
cookie is valid within. Pages outside
of that path cannot read or use the
cookie. If Path is not set explicitly,
then it defaults to the URL path of the
document creating the cookie.

Can silverlight detect or communicate across browser instances?

User starts up a silverlight application in their browser by navigating to a given URL.
User then opens another browser and starts up the same silverlight application by navigating to the same URL.
Can the second instance of the application detect that there is already an instance running on the same computer?
Can it detect itself if both applications are running within the same browser instance?
I would expect the answer to be 'no' but thought that i would ask it anyway. Otherwise i believe that i will have to setup a webservice and have each instance register itself and send requests to other instances from the same IP. does that sound reasonable?
I think you may be looking for LocalMessageSender and LocalMessageReceiver. I believe these are new classes in Silverlight 3 allowing two Silverlight applications running on the same local computer to communicate.
More detail: Communication Between Local Silverlight-Based Applications (msdn)
This will work, I've done it myself. This code from the Microsoft site demonstrates how you set up a LocalMessage 'receiver". If it throws an error, it is because another instance of the Silverlight app is already running.
public Receiver()
{
InitializeComponent();
LocalMessageReceiver messageReceiver =
new LocalMessageReceiver("receiver",
ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
messageReceiver.MessageReceived += messageReceiver_MessageReceived;
try
{
messageReceiver.Listen();
}
catch (ListenFailedException)
{
output.Text = "Cannot receive messages." + Environment.NewLine +
"There is already a receiver with the name 'receiver'.";
}
}
I think you're right you can't do it cross-application, but you can do it within a single browser instance using cookies or Isolated Storage.

Resources