Authentication​
Windows Auth Provider for ASP.NET​
An ASP.NET WindowsAuth Provider preview is available. This essentially wraps the existing Windows Auth support baked into ASP.NET and adds an adapter for ServiceStack's Multi-Provider Authentication model.
It can be registered just like any other Auth Provider, i.e. in the AuthFeature plugin:
Plugins.Add(new AuthFeature(
() => new CustomUserSession(),
new IAuthProvider[] {
new AspNetWindowsAuthProvider(this) { AllowAllWindowsAuthUsers = true },
}
));
By default it only allows access to users in AspNetWindowsAuthProvider.LimitAccessToRoles
, but can be overridden with AllowAllWindowsAuthUsers=true
to allow access to all Windows Auth users as seen in the example above.
Credentials can be attached to ServiceStack's Service Clients the same way as .NET WebRequest's by assingning the Credentials
property, e.g:
var client = new JsonServiceClient(BaseUri) {
Credentials = CredentialCache.DefaultCredentials,
};
var response = client.Get(new RequiresAuth { Name = "Haz Access!" });
To help with debugging, ?debug=requestinfo has been extended to include the Request's current Logon User info:
We're interested in hearing future use-cases this can support, feedback on this and future integration with Windows Auth are welcomed on the Active Directory Integration feature request.
New GitHub and other OAuth Providers available​
Thanks to Rouslan Grabar we now have a number of new OAuth providers built into ServiceStack, including authentication with GitHub, Russia's most popular search engine Yandex and Europe's largest Social Networks after Facebook, VK and Odnoklassniki:
Plugins.Add(new AuthFeature(
() => new CustomUserSession(),
new IAuthProvider[] {
new GithubAuthProvider(appSettings),
new YandexAuthProvider(appSettings),
new VkAuthProvider(appSettings),
new OdnoklassnikiAuthProvider(appSettings),
}
));
Extended Auth DTO's​
You can now test whether a user is authenticated by calling the Auth Service without any parameters, e.g. /auth
which will return summary auth info of the currently authenticated user or a 401
if the user is not authenticated. A DisplayName
property was added to AuthenticateResponse
to return a friendly name of the currently authenticated user.
Portable ServiceStack​
A new ServiceStack.Gap Repository and NuGet package was added to help with creating ServiceStack-powered Desktop applications.
ServiceStack has a number of features that's particularly well-suited for these kind of apps:
- It allows your services to be self-hosted using .NET's HTTP Listener
- It supports pre-compiled Razor Views
- It supports Embedded resources
- It supports an embedded database in Sqlite and OrmLite
- It can be ILMerged into a single .exe
Combined together this allows you to encapsulate your ServiceStack application into a single cross-platform .exe that can run on Windows or OSX.
To illustrate the potential of embedded ServiceStack solutions, a portable version httpbenchmarks.servicestack.net was created targetting a number of platforms below:
BenchmarksAnalyzer.zip - Single .exe that opens the BenchmarksAnalyzer app in the users browser
BenchmarksAnalyzer.Mac.zip - Self-hosted app running inside a OSX Cocoa App Web Browser
BenchmarksAnalyzer.Windows.zip - Self-hosted app running inside a Native WinForms app inside CEF
Usage​
By default BenchmarksAnalyzer.exe
will scan the directory where it's run from, it also supports being called with the path to .txt
or .zip
files to view or even a directory where output files are located. Given this there are a few popular ways to use Benchmarks Analyzer:
- Drop
BenchmarksAnalyzer.exe
into a directory of benchmark outputs before running it - Drop a
.zip
or folder onto theBenchmarksAnalyzer.exe
to view those results
Note: It can also be specified as a command-line argument, e.g: "BenchmarksAnalyzer.exe path\to\outputs"
ServiceStack.Gap Developer Guide​
The guides on how each application was created is on ServiceStack.Gap site, i.e:
- Self-Hosting Console App
- Windows Forms App with Chromium Embedded Framework and CefSharp
- Mac OSX Cocoa App with Xmarain.Mac
Other Framework Features​
Filtering support added to Metadata pages​
You can now filter services on ServiceStack's /metadata
page:
Typed Request Filters​
A more typed API to register Global Request and Response filters per Request DTO Type are available under the RegisterTyped*
API's in AppHost. These can be used to provide more flexibility in multi-tenant solutions by attaching custom data on incoming requests, e.g:
public override void Configure(Container container)
{
RegisterTypedRequestFilter<Resource>((req, res, dto) =>
{
var route = req.GetRoute();
if (route != null && route.Path == "/tenant/{TenantName}/resource")
{
dto.SubResourceName = "CustomResource";
}
});
}
Typed Filters can also be used to apply custom behavior on Request DTO's sharing a common interface, e.g:
public override void Configure(Container container)
{
RegisterTypedRequestFilter<IHasSharedProperty>((req, res, dtoInterface) => {
dtoInterface.SharedProperty = "Is Shared";
});
}
Buffered Stream option has now added to Response​
Response streams can be buffered in the same way as you can buffer Request streams by setting UseBufferedStream=true
, e.g:
appHost.PreRequestFilters.Add((httpReq, httpRes) => {
httpReq.UseBufferedStream = true;
httpRes.UseBufferedStream = true;
});
AfterInitCallbacks added to AppHost​
You can register callbacks to add custom logic straight after the AppHost has finished initializing. E.g. you can find all Roles specified in [RequiredRole]
attributes with:
appHost.AfterInitCallbacks.Add(host =>
{
var allRoleNames = host.Metadata.OperationsMap
.SelectMany(x => x.Key.AllAttributes<RequiredRoleAttribute>()
.Concat(x.Value.ServiceType.AllAttributes<RequiredRoleAttribute>()))
.SelectMany(x => x.RequiredRoles);
});
Request Scopes can be configured to use ThreadStatic​
Request Scoped dependencies are stored in HttpRequest.Items
for ASP.NET hosts and uses Remoting's CallContext.LogicalData
API's in self-hosts. Using the Remoting API's can be problematic in old versions of Mono or when executed in test runners.
If this is an issue the RequestContext can be configured to use ThreadStatic with:
RequestContext.UseThreadStatic = true;
Logging​
Updated Logging providers to allow debugEnabled
in their LogFactory constructor, e.g:
LogFactory.LogManager = new NullLogFactory(debugEnabled:false);
LogFactory.LogManager = new ConsoleLogFactory(debugEnabled:true);
LogFactory.LogManager = new DebugLogFactory(debugEnabled:true);
Detailed command logging is now enabled in OrmLite and Redis when debugEnabled=true
. The external Logging provider NuGet packages have also been updated to use their latest version.
Razor​
- Enabled support for Razor
@helpers
and@functions
in Razor Views - Direct access to Razor Views in
/Views
is now denied by default
Service Clients​
- Change Silverlight to auto emulate HTTP Verbs for non GET or POST requests
- Shorter aliases added on
PostFileWithRequest
which uses the Request DTO's auto-generated url - The PCL version of ServiceStack.Interfaces now supports a min version of .NET 4.0
OrmLite​
Exec and Result Filters​
A new CaptureSqlFilter
Results Filter has been added which shows some of the power of OrmLite's Result filters by being able to capture SQL Statements without running them, e.g:
public class CaptureSqlFilter : OrmLiteResultsFilter
{
public CaptureSqlFilter()
{
SqlFilter = CaptureSql;
SqlStatements = new List<string>();
}
private void CaptureSql(string sql)
{
SqlStatements.Add(sql);
}
public List<string> SqlStatements { get; set; }
}
This can then be wrapped around existing database calls to capture and print the generated SQL, e.g:
using (var captured = new CaptureSqlFilter())
using (var db = OpenDbConnection())
{
db.CreateTable<Person>();
db.Count<Person>(x => x.Age < 50);
db.Insert(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" });
db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
sql.Print();
}
Exec filters can be limited to specific Dialect Providers​
OrmLiteConfig.DialectProvider.ExecFilter = execFilter;
OrmLite's custom SqlBuilders now implement ISqlExpression​
OrmLite provides good support in integrating with external or custom SQL builders that implement OrmLite's simple ISqlExpression
interface which can be passed directly to db.Select()
API. This has now been added to OrmLite's other built-in SQL Builders, e.g:
Using JoinSqlBuilder​
var joinQuery = new JoinSqlBuilder<User, User>()
.LeftJoin<User, Address>(x => x.Id, x => x.UserId,
sourceWhere: x => x.Age > 18,
destinationWhere: x => x.Country == "Italy");
var results = db.Select<User>(joinQuery);
Using SqlBuilder​
var tmpl = sb.AddTemplate(
"SELECT * FROM User u INNER JOIN Address a on a.UserId = u.Id /**where**/");
sb.Where("Age > @age", new { age = 18 });
sb.Where("Countryalias = @country", new { country = "Italy" });
var results = db.Select<User>(tmpl, tmpl.Parameters);
Other Changes​
- OrmLite can create tables with any numeric type in all providers. Fallbacks were added on ADO.NET providers that don't support the numeric type natively
- Load/Save Reference property conventions can be inferred on either aliases or C# property names
- OrmLite can create tables from types with Indexers
- Can use
OrmLiteConfig.StripUpperInLike=true
to remove use of upper() in Sql Expressions
Redis​
A new TrackingRedisClientsManager
client manager has been added by Thomas James to help diagnose Apps that are leaking redis connections.