title |
---|
ServiceStack v4.0.21 |
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.
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),
}
));
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.
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
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"
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
You can now filter services on ServiceStack's /metadata
page:
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";
});
}
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;
});
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 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;
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.
- Enabled support for Razor
@helpers
and@functions
in Razor Views - Direct access to Razor Views in
/Views
is now denied by default
- 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
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();
}
OrmLiteConfig.DialectProvider.ExecFilter = execFilter;
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:
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);
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);
- 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
A new TrackingRedisClientsManager
client manager has been added by Thomas James to help diagnose Apps that are leaking redis connections.